RT,代码如下
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int N=1e6+1;
int fa[N][21];
int depth[N];
int st[N];
int ans[N];
int head[N],tot;
// vector<int> G[N];
queue<int> q;
struct Edge
{
int to,next;
}edge[N];
void add(int u,int v)
{
edge[++tot].next=head[u];
edge[tot].to=v;
head[u]=tot;
}
struct Query
{
int dep,id,u;
Query(int dep=0,int id=0,int u=0):dep(dep),id(id),u(u){}
}Q[N];
// vector<Query> Q[N];
struct Node
{
int ls,rs,sum;
}T[N*25];
int root[N],cnt,n;
void dfs(int u,int dep)
{
// printf("%d\n",u);
depth[u]=dep;
for (int i=1;(1<<i)<=depth[u];++i)
fa[u][i]=fa[fa[u][i-1]][i-1];
for (int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
dfs(v,dep+1);
}
}
inline int get_anc(int u,int k)
{
for (int i=0;(1<<i)<=n;++i)
if (k&(1<<i)) u=fa[u][i];
return u;
}
int merge(int x,int y)
{
if (!x || !y) return x|y;
T[x].sum+=T[y].sum;
q.push(y);
T[x].ls=merge(T[x].ls,T[y].ls);
T[x].rs=merge(T[x].rs,T[y].rs);
return x;
}
void pushup(int o)
{
T[o].sum=T[T[o].ls].sum+T[T[o].rs].sum;
}
int new_node()
{
if (q.empty()) return ++cnt;
int r=q.front();q.pop();
T[r].ls=T[r].rs=T[r].sum=0;
return r;
}
void insert(int l,int r,int &o,int val)
{
if (!o) o=new_node();
if (l==r) return (void)(T[o].sum++);
int mid=(l+r)>>1;
if (val<=mid) insert(l,mid,T[o].ls,val);
else insert(mid+1,r,T[o].rs,val);
pushup(o);
}
int query(int l,int r,int o,int p)
{
if (!o) return 0;
if (l==r) return T[o].sum;
int mid=(l+r)>>1;
if (p<=mid) return query(l,mid,T[o].ls,p);
else return query(mid+1,r,T[o].rs,p);
}
void dfs2(int u,int n)
{
for (int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
dfs2(v,n),root[u]=merge(root[u],root[v]);
}
insert(1,n,root[u],depth[u]);
for (int i=st[u];Q[i].u==u;++i)
ans[Q[i].id]=query(1,n,root[u],Q[i].dep);
}
int main()
{
scanf("%d",&n);
int m;
scanf("%d",&m);
for (int i=2;i<=n;++i)
{
scanf("%d",&fa[i][0]);
add(fa[i][0],i);
}
// for (int i=1;i<=n;++i) G[i].shrink_to_fit();
dfs(1,1);
for (int i=1;i<=m;++i)
{
int v,p;
scanf("%d%d",&v,&p);
int r=get_anc(v,p);
// printf("%d\n",r);
if (r>=1) Q[i]=Query(depth[v],i,r);
}
sort(Q+1,Q+m+1,[](const Query &a,const Query &b) ->bool {return a.u<b.u;});
for (int i=1;i<=m;++i)
if (Q[i].u!=Q[i-1].u)
st[Q[i].u]=i;
// for (int i=1;i<=n;++i) Q[i].shrink_to_fit();
dfs2(1,n);
for (int i=1;i<=m;++i)
printf("%d ",ans[i]?ans[i]-1:0);
}