首先考虑没有深度限制,即对一颗子树求颜色数,那么可以用树上差分,根据dfs序,每个点和这个颜色在dfs中上一次出现点的lca打-1,然后每个点再打上一个+1,然后求一颗子树内所有节点的标记和即为答案。
为了深度限制,因此可以以深度为时间建一棵可持久化线段树,然后查询(x,d)即查询第deep[x]+d层的以x为根的子树,同时过程中可以维护当前插入的节点中每一个颜色的set(根据dfs排序)来处理lca的加减。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100001 4 #define mid (l+r>>1) 5 struct ji{ 6 int nex,to; 7 }edge[N<<1]; 8 int E,V,t,n,m,x,y,k,sz[N],c[N],r[N],sh[N],head[N],out[N],in[N],df[N],ndf[N],f[N][21],ls[N*100],rs[N*100],tr[N*100]; 9 set<int>se[N]; 10 struct node{ 11 int d,id; 12 }a[N]; 13 bool cmp(node x,node y){ 14 return x.d<y.d; 15 } 16 void add(int x,int y){ 17 edge[E].nex=head[x]; 18 edge[E].to=y; 19 head[x]=E++; 20 } 21 void dfs(int k,int s){ 22 sz[k]=1; 23 sh[k]=s; 24 ndf[df[k]=++df[0]]=k; 25 in[k]=++x; 26 for(int i=head[k];i!=-1;i=edge[i].nex){ 27 dfs(edge[i].to,s+1); 28 sz[k]+=sz[edge[i].to]; 29 } 30 out[k]=++x; 31 } 32 bool pd(int x,int y){ 33 return (in[x]<=in[y])&&(out[y]<=out[x]); 34 } 35 int lca(int x,int y){ 36 if (pd(x,y))return x; 37 if (pd(y,x))return y; 38 for(int j=20;j>=0;j--) 39 if (!pd(f[x][j],y))x=f[x][j]; 40 return f[x][0]; 41 } 42 void update(int k1,int &k2,int l,int r,int x,int y){ 43 if ((x<l)||(x>r)||(l>r))return; 44 tr[k2=++V]; 45 ls[k2]=rs[k2]=0; 46 if (l==r){ 47 tr[k2]=tr[k1]+y; 48 return; 49 } 50 update(ls[k1],ls[k2]=ls[k1],l,mid,x,y); 51 update(rs[k1],rs[k2]=rs[k1],mid+1,r,x,y); 52 tr[k2]=tr[ls[k2]]+tr[rs[k2]]; 53 } 54 int query(int k,int l,int r,int x,int y){ 55 if ((x>r)||(l>y)||(l>r))return 0; 56 if ((x<=l)&&(r<=y))return tr[k]; 57 return query(ls[k],l,mid,x,y)+query(rs[k],mid+1,r,x,y); 58 } 59 int main(){ 60 scanf("%d",&t); 61 while (t--){ 62 scanf("%d%d",&n,&m); 63 for(int i=1;i<=n;i++)scanf("%d",&c[i]); 64 memset(head,-1,sizeof(head)); 65 E=V=df[0]=0; 66 memset(r,0,sizeof(r)); 67 for(int i=2;i<=n;i++){ 68 scanf("%d",&x); 69 add(f[i][0]=x,i); 70 } 71 dfs(1,1); 72 f[1][0]=1; 73 for(int j=1;j<=20;j++) 74 for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1]; 75 for(int i=1;i<=n;i++) a[i].id=i,a[i].d=sh[i]; 76 sort(a+1,a+n+1,cmp); 77 for(int i=1;i<=n;i++)se[i].clear(); 78 for(int i=1;i<=n;i++){ 79 k=a[i].id; 80 update(r[sh[a[i-1].id]],r[sh[k]],1,n,df[k],1); 81 x=y=0; 82 set<int>::iterator it=se[c[k]].lower_bound(df[k]); 83 if (it!=se[c[k]].end())x=ndf[*it]; 84 if (it!=se[c[k]].begin())y=ndf[*(--it)]; 85 if (x)update(r[sh[k]],r[sh[k]],1,n,df[lca(x,k)],-1); 86 if (y)update(r[sh[k]],r[sh[k]],1,n,df[lca(y,k)],-1); 87 if ((x)&&(y))update(r[sh[k]],r[sh[k]],1,n,df[lca(x,y)],1); 88 se[c[k]].insert(df[k]); 89 } 90 k=0; 91 for(int i=1;i<=n;i++) if(!r[i]) r[i]=r[i-1]; 92 while (m--){ 93 scanf("%d%d",&x,&y); 94 x^=k; 95 y^=k; 96 y=min(y+sh[x],n); 97 printf("%d\n",k=query(r[y],1,n,df[x],df[x]+sz[x]-1)); 98 } 99 } 100 }