题解:CF208E
NTT__int128 · · 题解
CF208E 题解
这里提供一个比较劣的做法。
对于每次询问,求出
时间复杂度:
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,K=4e2+5;
int n,fa[N],m,dp[N][20],lg[N],t,l[K],r[K],pos[N],dfn[N],siz[N],ans[N],cnt,c[N],dep[N],rnk[N];
struct ask{
int l,r,v,id;
bool operator<(const ask&_)const{
return (pos[l]==pos[_.l]?(r==_.r?0:r<_.r):l<_.l);
}
}q[N];
vector<int>v[N];
void dfs(int cur){
dfn[cur]=++cnt,rnk[cnt]=cur,siz[cur]=1,dp[cur][0]=fa[cur],dep[cur]=dep[fa[cur]]+1;
for(int i=1;i<=lg[dep[cur]];i++)dp[cur][i]=dp[dp[cur][i-1]][i-1];
for(int to:v[cur])dfs(to),siz[cur]+=siz[to];
}
void add(int x){c[dep[rnk[x]]]++;}
void del(int x){c[dep[rnk[x]]]--;}
int main(){
cin>>n;
lg[0]=-1;
for(int i=1;i<=n;i++){
cin>>fa[i];
if(fa[i])v[fa[i]].push_back(i);
lg[i]=lg[i>>1]+1;
}
for(int i=1;i<=n;i++)if(!fa[i])dfs(i);
int t=sqrt(n);
for(int i=1;i<=t;i++)l[i]=r[i-1]+1,r[i]=i*t;
if(r[t]<n)t++,l[t]=r[t-1]+1,r[t]=n;
for(int i=1;i<=t;i++)for(int j=l[i];j<=r[i];j++)pos[j]=i;
cin>>m;
cnt=0;
for(int i=1;i<=m;i++){
int x,l;
cin>>x>>l;
if(l>=dep[x])continue;
cnt++;
q[cnt].v=dep[x];
while(l)x=dp[x][lg[l]],l-=(1<<lg[l]);
q[cnt].l=dfn[x],q[cnt].r=dfn[x]+siz[x]-1,q[cnt].id=i;
}
sort(q+1,q+cnt+1);
int l=1,r=0;
for(int i=1;i<=cnt;i++){
while(l>q[i].l)add(--l);
while(r<q[i].r)add(++r);
while(l<q[i].l)del(l++);
while(r>q[i].r)del(r--);
ans[q[i].id]=c[q[i].v]-1;
}
for(int i=1;i<=m;i++)cout<<ans[i]<<' ';
return 0;
}