dsu on tree WA#8求调
查看原帖
dsu on tree WA#8求调
605945
luo_xiaoran楼主2024/5/4 08:32
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,m,tot,head[N],sz[N],son[N],cnt[N],up[N][20],dep[N],ans[N];
struct Edge{
	int v,nxt;
}e[N];
struct Node{
	int id,dis;
};
vector<Node> q[N];
void add(int u,int v){
	e[++tot]={v,head[u]};
	head[u]=tot;
}
void dfs1(int u){
	++dep[u],sz[u]=1;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].v;
		dep[v]=dep[u];
		dfs1(v);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]]) son[u]=v;
	}
}
int fa(int u,int dis){
	dis=dep[u]-dis;
	for(int i=20;i>=0;--i) if(dep[up[u][i]]>=dis) u=up[u][i];
	return u;
}
void dfs2(int u,int ch){
	cnt[dep[u]]+=ch;
	for(int i=head[u];i;i=e[i].nxt) dfs2(e[i].v,ch);
}
void dsu(int u,bool mode){
	for(int i=head[u];i;i=e[i].nxt) if(e[i].v!=son[u]) dsu(e[i].v,0);
	if(son[u]) dsu(son[u],1);
	for(int i=head[u];i;i=e[i].nxt) if(e[i].v!=son[u]) dfs2(e[i].v,1);
	++cnt[dep[u]];
	for(int i=0;i<q[u].size();++i) ans[q[u][i].id]=cnt[dep[u]+q[u][i].dis];
	if(!mode) dfs2(u,-1);
}
signed main(){
	scanf("%lld",&n);
	for(int i=1,u;i<=n;++i){
		scanf("%lld",&u);
		if(u) add(u,i),up[i][0]=u;
	}
	for(int i=1;i<=n;++i) if(!up[i][0]) dfs1(i);
	for(int j=1;j<=18;++j)
		for(int i=1;i<=n;++i) up[i][j]=up[up[i][j-1]][j-1];
	scanf("%lld",&m);
	for(int i=1,v,p;i<=m;++i){
		scanf("%lld%lld",&v,&p);
		int u=fa(v,p);
		if(u) q[u].push_back({i,p});
	}
	for(int i=1;i<=n;++i) if(!up[i][0]) dsu(i,0);
	for(int i=1;i<=m;++i) printf("%lld ",max(ans[i]-1,0ll));
	return 0;
}
2024/5/4 08:32
加载中...