题意 : 求每个子树中有多少种不同的颜色
我们先dfs处理出每棵子树的区间 , 然后莫队就好了
唯一需要注意的是 , dfs后需要将颜色按dfs序重新标号
#include<bits/stdc++.h>
#define N 100050
using namespace std;
int first[N],next[N],to[N],tot;
int st[N],ed[N],col[N],sign;
int n,m,pos[N],cnt[N],ans[N],tmp;
struct Node{int l,r,id;}q[N];
void add(int x,int y){
next[++tot]=first[x],first[x]=tot,to[tot]=y;
}
bool cmp(Node a,Node b){
if(pos[a.l]==pos[b.l]) return a.r<b.r;
return pos[a.l]<pos[b.l];
}
void dfs(int u){
st[u] = ++sign;
for(int i=first[u];i;i=next[i]){
int t=to[i]; dfs(t);
} ed[u] = sign;
}
void add(int x){if(cnt[x]==0) tmp++; cnt[x]++;}
void del(int x){if(cnt[x]==1) tmp--; cnt[x]--;}
int main(){
scanf("%d",&n); int siz = sqrt(n);
for(int i=2;i<=n;i++){
int x; scanf("%d",&x); add(x,i);
} dfs(1);
for(int i=1;i<=n;i++){
scanf("%d",&col[st[i]]); pos[i] = i/siz;
} scanf("%d",&m);
for(int i=1;i<=m;i++){
int x; scanf("%d",&x);
q[i].l=st[x] , q[i].r=ed[x] , q[i].id=i;
} sort(q+1,q+m+1,cmp); int l=1,r=0;
for(int i=1;i<=m;i++){
while(r<q[i].r) add(col[++r]); while(r>q[i].r) del(col[r--]);
while(l<q[i].l) del(col[l++]); while(l>q[i].l) add(col[--l]);
ans[q[i].id] = tmp;
}
for(int i=1;i<=m;i++) printf("%d\n",ans[i]); return 0;
}