思路:

1.询问一个点与多少个点拥有共同的级祖先,可以理解为一个点的级祖先有多少个级儿子
即有多少深度为的孩子,最后答案别忘了 ,因为把自己也算了在内
2.求出相关的点的级祖先可以用求的倍增法
3.将每次查询用容器存储,方便离线操作
4.题目给的是森林,需要存每颗树的根节点
复杂度:

MyCode:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7,maxm=1e5+7;
typedef long long ll;
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
int head[maxn],Next[maxm],to[maxm],tot;
void add(int x,int y) {
    to[++tot]=y;
    Next[tot]=head[x];
    head[x]=tot;
}
int size[maxn],son[maxn],dep[maxn];
int cnt[maxn],ans[maxn],dp[maxn][20];
bool vis[maxn];
int que[maxn];
#define x first
#define y second
vector<pair<int,int> >query[maxn];
void dfs1(int x,int f) {
    size[x]=1;
    dep[x]=dep[f]+1;
    dp[x][0]=f;
    for(int i=1;i<18;++i) if(dp[x][i-1]!=-1)
        dp[x][i]=dp[dp[x][i-1]][i-1];
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        dfs1(v,x);
        size[x]+=size[v];
        if(size[son[x]]<size[v]) son[x]=v;
    }
}
void calc(int x) {
    cnt[dep[x]]+=1;
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        if(vis[v]) continue;
        calc(v);
    }
}
void delet(int x) {
    cnt[dep[x]]-=1;
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        delet(v);
    }
}
void dfs2(int x,bool opt) {
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        if(son[x]==v) continue;
        dfs2(v,false);
    }
    if(son[x]) {
        dfs2(son[x],true);
        vis[son[x]]=true;
    }
    calc(x);
    int size=query[x].size();
    if(size) {
        for(int i=0;i<size;++i) 
            ans[query[x][i].x]=cnt[query[x][i].y]-1;
    }
    if(son[x]) vis[son[x]]=false;
    if(!opt) delet(x);
}
int main() {
    int n=read(),top=0;
    memset(dp,-1,sizeof dp);
    for(int i=1,u;i<=n;++i) {
        u=read();
        if(u) add(u,i);
        else que[++top]=i;
    }
    int m=read();
    for(int i=1;i<=top;++i) dfs1(que[i],0);
    for(int i=1,a,k,tmp;i<=m;++i) {
        a=read(),k=read();
        for(int i=17;i>=0;--i) if((1<<i)&k)
            a=dp[a][i];
        query[a].push_back(make_pair(i,dep[a]+k));
    }
    for(int i=1;i<=top;++i) dfs2(que[i],false);
    for(int i=1;i<=m;++i) printf("%d ",ans[i]);
    return 0;
}