rt,WA#8.
思路就是先拍成序列,然后分块维护每一块值为 k 的数的数的个数。代码如下:
#include<bits/stdc++.h>
using namespace std;
int dep[100005];
int dfn[100005];
int tot=-1,n,r[100005];
int num[100005][320]={0},l[320],id[100005];
vector<int> G[100005];
int fa[100005][35];
int Log2[100005];
void logg()
{
Log2[0]=Log2[1]=0;
for(int i=2;i<=100002;i++)
Log2[i]=Log2[i/2]+1;
}
int KZX(int x,int k)
{
int f=0;
while(k)
{
if(k%2) x=fa[x][f];
f++,k/=2;
}
return x;
}
void dfs(int x)
{
dfn[x]=++tot;
dep[x]=dep[fa[x][0]]+1;
for(int i=1;i<=Log2[dep[x]];i++)
fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=0;i<G[x].size();i++)
dfs(G[x][i]);
r[x]=tot;
}
void ycl()
{
int kc=sqrt(n);
tot=0;
for(int i=1;i<=n;i++)
{
id[i]=(i-1)/kc+1;
if(id[i]!=id[i-1]) l[++tot]=i;
}
l[1+tot]=n+1;
for(int i=1;i<=n;i++)
num[dep[i]][id[i]]++;
}
int update(int L,int R,int k)
{
int idl=id[L],idr=id[R],ans=0;
if(idl==idr)
{
for(int i=L;i<=R;i++) ans+=(dep[i]==k);
return ans-1;
}
else
{
for(int i=L;i<l[idl+1];i++) ans+=(dep[i]==k);
for(int i=l[idr];i<=R;i++) ans+=(dep[i]==k);
for(int i=idl+1;i<idr;i++) ans+=num[k][i];
return ans-1;
}
}
void solve()
{
int v,p;
cin>>v>>p;
int vp=KZX(v,p);
if(vp==0) cout<<"0 ";
else cout<<max(update(dfn[vp],r[vp],dep[v]),0)<<' ';
}
signed main()
{
logg();
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>fa[i][0];
G[fa[i][0]].push_back(i);
}
dep[0]=-1;
dfs(0);
ycl();
int q;
for(cin>>q;q--;solve());
return 0;
}