对于一个询问(x,y)对y出现次数分类,若<=lim,在儿子处统计答案,若>lim则y的种类肯定<lim,在祖先处统计(仿佛要去重?但是没去重也过了,那个时限仿佛怎么做都能过)
#include<cstdio>
#include<algorithm>
#include<vector>
#define pr pair<int,int>
#define mp make_pair
#define fr first
#define sc second
using namespace std;
int cnt,last[1000005],Sum[1000005],c[1000005],sz[1000005];
long long ANS[1000005];
vector<pr> vec1[1000005],vec2[1000005];
struct node{
int to,next;
}e[1000005];
void add(int a,int b){
e[++cnt].to=b;
e[cnt].next=last[a];
last[a]=cnt;
}
void solve1(int x,int fa){
for (int i=0; i<(int)vec1[c[x]].size(); i++){
pr q=vec1[c[x]][i];
ANS[q.fr]+=Sum[q.sc];
}
Sum[c[x]]++;
for (int i=last[x]; i; i=e[i].next){
int V=e[i].to;
if (V==fa) continue;
solve1(V,x);
}
Sum[c[x]]--;
}
void solve2(int x,int fa){
Sum[c[x]]++;
for (int i=0; i<(int)vec2[c[x]].size(); i++){
pr q=vec2[c[x]][i];
ANS[q.fr]-=Sum[q.sc];
}
for (int i=last[x]; i; i=e[i].next){
int V=e[i].to;
if (V==fa) continue;
solve2(V,x);
}
for (int i=0; i<(int)vec2[c[x]].size(); i++){
pr q=vec2[c[x]][i];
ANS[q.fr]+=Sum[q.sc];
}
}
int main(){
int n,R,q;
scanf("%d%d%d",&n,&R,&q);
scanf("%d",&c[1]);
sz[c[1]]++;
int lim=500;
for (int i=2; i<=n; i++){
int x;
scanf("%d%d",&x,&c[i]);
sz[c[i]]++;
add(x,i);
add(i,x);
}
for (int i=1; i<=q; i++){
int X,Y;
scanf("%d%d",&X,&Y);
if (sz[Y]<=lim) vec1[Y].push_back(mp(i,X));
else vec2[X].push_back(mp(i,Y));
}
solve1(1,0);
solve2(1,0);
for (int i=1; i<=q; i++) printf("%lld\n",ANS[i]);
return 0;
}