1782: [Usaco2010 Feb]slowdown 慢慢游

来源:互联网 发布:linux 查看权限 编辑:程序博客网 时间:2024/05/18 22:43

题目链接

题目大意:有n头牛从树上的一个点到达另一个点,求每头牛经过其他牛的个数

题解:当一头牛到达一个点x后,所有终点在以x为根的子树中的牛答案+1,区间修改,单点查询dfs序就好了。Orz hzwer写法

我的收获:劲

#include<iostream>#include<cstdio>#include<cstring>#define N 100005using namespace std;inline int read(){    int x=0;char ch=getchar();    while(ch<'0'||ch>'9')ch=getchar();    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x;}int n,cnt;int p[N],ans[N],head[N],t[N];struct data{int to,next;}e[N+N];void ins(int u,int v){e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}void insert(int u,int v){ins(u,v);ins(v,u);}inline int lowbit(int x){return x&(-x);}void update(int x,int val){for(int i=x;i<=n;i+=lowbit(i))t[i]+=val;}int ask(int x){    int sum=0;    for(int i=x;i>0;i-=lowbit(i))        sum+=t[i];    return sum;}void dfs(int x,int fa){    ans[p[x]]=ask(p[x]);    update(p[x],1);//x点对询问比它晚(p[x]值大),x及的子树(dfs搜索顺序保证)的点有贡献    for(int i=head[x];i;i=e[i].next)        if(e[i].to!=fa)            dfs(e[i].to,x);    update(p[x],-1);}int main(){    n=read();    for(int i=1;i<n;i++)        insert(read(),read());    for(int i=1;i<=n;i++)        p[read()]=i;//按询问次序排列    dfs(1,0);    for(int i=1;i<=n;i++)        printf("%d\n",ans[i]);    return 0;}
原创粉丝点击