链剖,应该用这道来入门啊= =,只顾下传标记就行。。
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(i=l;i<=r;i++) 3 #define dec(i,l,r) for(i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define NM 300000+5 10 using namespace std; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 14 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 15 return x*f; 16 } 17 struct info{ 18 int z,s; 19 }T[8*NM]; 20 struct edge{ 21 int t; 22 edge *next; 23 }e[2*NM],*h[NM],*p=e; 24 int f[NM],id[NM],_id[NM],son[NM],d[NM],size[NM],top[NM],TOP,tot; 25 int n,m,_x,_y,l,r,a[NM],_v; 26 void add(int x,int y){ 27 p->t=y;p->next=h[x];h[x]=p;p++; 28 } 29 void dfs1(int x){ 30 link(x) 31 if(!f[j->t]){ 32 f[j->t]=x; 33 d[j->t]=d[x]+1; 34 dfs1(j->t); 35 size[x]+=size[j->t]; 36 if(size[j->t]>size[son[x]])son[x]=j->t; 37 } 38 size[x]++; 39 } 40 void dfs2(int x){ 41 top[x]=TOP;id[x]=++tot;_id[tot]=x; 42 if(son[x])dfs2(son[x]); 43 link(x) 44 if(!top[j->t])dfs2(TOP=j->t); 45 } 46 void pushdown(int i){ 47 if(T[i].z){ 48 T[i<<1].s+=T[i].z;T[i<<1|1].s+=T[i].z; 49 T[i<<1].z+=T[i].z;T[i<<1|1].z+=T[i].z; 50 T[i].z=0; 51 } 52 } 53 void add(int i,int x,int y){ 54 int t=x+y>>1; 55 if(l<=x&&y<=r){ 56 T[i].z+=_v;T[i].s+=_v; 57 return; 58 } 59 if(r<x||y<l)return; 60 pushdown(i); 61 add(i<<1,x,t);add(i<<1|1,t+1,y); 62 } 63 void ans(int i,int x,int y){ 64 int t=x+y>>1; 65 if(x==y){ 66 a[_id[x]]=T[i].s; 67 return; 68 } 69 pushdown(i); 70 ans(i<<1,x,t);ans(i<<1|1,t+1,y); 71 } 72 int main(){ 73 int i; 74 n=read(); 75 inc(i,1,n)a[i]=read(); 76 inc(i,1,n-1){ 77 _x=read();_y=read(); 78 add(_x,_y);add(_y,_x); 79 } 80 f[1]=1; 81 dfs1(1); 82 dfs2(TOP=1); 83 inc(i,1,n-1){ 84 _x=a[i];_y=a[i+1]; 85 _v=1; 86 while(top[_x]!=top[_y]){ 87 if(d[top[_x]]<d[top[_y]])swap(_x,_y); 88 l=id[top[_x]];r=id[_x]; 89 add(1,1,n); 90 _x=f[top[_x]]; 91 } 92 if(d[_x]>d[_y])swap(_x,_y); 93 l=id[_x];r=id[_y];_v=1; 94 add(1,1,n); 95 l=r=id[a[i+1]];_v=-1; 96 add(1,1,n); 97 // ans(1,1,n);printf(" "); 98 } 99 ans(1,1,n); 100 inc(i,1,n)printf("%d ",a[i]); 101 return 0; 102 }