CF1009F Dominant Indices

给你一棵树,定义(d_{x,i})表示(x)子树内和(x)距离为(i)的节点数,对每个(x)求使(d_{x,i})最大的(i),如有多个输出最小的。

不知道什么是长链剖分的可以看看蒟蒻的笔记

长链剖分的板子,具体看代码应该能懂

//minamoto
#include<bits/stdc++.h>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
int read(){
    int res,f=1;char ch;
    while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
    for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
    return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(int x){
    if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
    while(z[++Z]=x%10+48,x/=10);
    while(sr[++C]=z[Z],--Z);sr[++C]='
';
}
const int N=1e6+5;
int head[N],Next[N<<1],ver[N<<1],tot;
inline void add(int u,int v){ver[++tot]=v,Next[tot]=head[u],head[u]=tot;}
int len[N],son[N],tmp[N],*f[N],*id=tmp,ans[N],n;
void dfs(int u,int fa){
	for(int i=head[u];i;i=Next[i])if(ver[i]!=fa){
		dfs(ver[i],u);
		if(len[ver[i]]>len[son[u]])son[u]=ver[i];
	}
	len[u]=len[son[u]]+1;
}
void dp(int u,int fa){
	f[u][0]=1;if(son[u])f[son[u]]=f[u]+1,dp(son[u],u),ans[u]=ans[son[u]]+1;
	for(int i=head[u];i;i=Next[i]){
		int v=ver[i];if(v==fa||v==son[u])continue;
		f[v]=id,id+=len[v],dp(v,u);
		for(int j=1;j<=len[v];++j){
			f[u][j]+=f[v][j-1];
			if((j<ans[u]&&f[u][j]>=f[u][ans[u]])||(j>ans[u]&&f[u][j]>f[u][ans[u]]))
			ans[u]=j;
		}
	}
	if(f[u][ans[u]]==1)ans[u]=0;
}
int main(){
//	freopen("testdata.in","r",stdin);
	n=read();
	for(int i=1,u,v;i<n;++i)u=read(),v=read(),add(u,v),add(v,u);
	dfs(1,0),f[1]=id,id+=len[1],dp(1,0);
	for(int i=1;i<=n;++i)print(ans[i]);
	return Ot(),0;
}
原文地址:https://www.cnblogs.com/bztMinamoto/p/9948452.html