bzoj1782: [Usaco2010 Feb]slowdown 慢慢游

来源:互联网 发布:fastdfs java 编辑:程序博客网 时间:2024/05/17 15:56

应该是树上搜索,但因为顺序不同而且情况会改变,搜索回溯什么的并不好使。

不过能发现,每一次更改对后面有影响,我们可以把影响记下来,用到线段树。

先用dfs找一遍每个点影响的范围,每走一次整个区间都加1。还是需要画一画的。

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct nn{int to,next;}edge[200500];int cnt;int head[200005];void add(int f,int t){edge[cnt].to=t;edge[cnt].next=head[f];head[f]=cnt++;}int n;int a[100005];int s[100005],e[100005];int tree[100005*4];int num;void dfs(int u,int f){s[u]=++num;for(int i=head[u];i!=-1;i=edge[i].next){if(edge[i].to==f)continue;dfs(edge[i].to,u);}e[u]=num;}void change(int l,int r,int st,int en,int node){if(st==l&&en==r)//注意,和普通的线段树并不一样{tree[node]++;return ;}int mid=(st+en)>>1;if(mid<l){change(l,r,mid+1,en,node<<1|1);}else if(mid>=r)//注意等号{change(l,r,st,mid,node<<1);}else{change(l,mid,st,mid,node<<1);change(mid+1,r,mid+1,en,node<<1|1);}}int quiry(int l,int r,int x,int node){if(l==r){return tree[node];}int mid=(l+r)>>1;if(x<=mid)return tree[node]+quiry(l,mid,x,node<<1);else return tree[node]+quiry(mid+1,r,x,node<<1|1);}int main(){memset(head,-1,sizeof(head));scanf("%d",&n);for(int i=1;i<n;i++){int a,b;scanf("%d %d",&a,&b);add(a,b);add(b,a);}for(int i=1;i<=n;i++){scanf("%d",&a[i]);}dfs(1,0);for(int i=1;i<=n;i++){printf("%d\n",quiry(1,n,s[a[i]],1));change(s[a[i]],e[a[i]],1,n,1);}}


0 0