luogu CF1009F Dominant Indices |线段树合并

题意翻译

给定一棵以 (1) 为根,(n) 个节点的树。设 (d(u,x))(u) 子树中到 (u) 距离为 (x) 的节点数。

对于每个点,求一个最小的 (k),使得 (d(u,k)) 最大。


#include <bits/stdc++.h>
using namespace std;
inline int read(){
	int res=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}	
	while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+ch-'0';ch=getchar();}
	return res*f;
}
const int N=2e6+5;
const int M=21000005;
int nxt[N<<1],head[N],go[N<<1],tot;
inline void add(int u,int v){
	nxt[++tot]=head[u],head[u]=tot,go[tot]=v;
	nxt[++tot]=head[v],head[v]=tot,go[tot]=u;
}
#define mid ((l+r)>>1)
int root[N],ls[M],rs[M],val[M],Max[M],cnt;
inline void pushup(int p){
	if(val[ls[p]]<val[rs[p]]){
		val[p]= val[rs[p]] ;
		Max[p]= Max[rs[p]] ;
	}else{
		val[p]= val[ls[p]] ;
		Max[p]= Max[ls[p]] ;
	}
}
void update(int &p,int l,int r,int pos,int d){
	if(!p)p=++cnt;
	if(l==r){ val[p]+=d; Max[p]=pos; return; }
	if(pos<=mid)update(ls[p],l,mid,pos,d);
	else update(rs[p],mid+1,r,pos,d);
	pushup(p);
}
int merge(int u,int v,int l,int r){
	if(!u || !v)return u|v;
	if(l==r){ val[u]+=val[v]; Max[u]=l; return u; }
	ls[u]=merge(ls[u],ls[v],l,mid);
	rs[u]=merge(rs[u],rs[v],mid+1,r);
	pushup(u);
	return u;
}
int ans[N],dep[N],n;
void dfs(int u,int fa){
	dep[u]=dep[fa]+1;
	update(root[u],1,n,dep[u],1);
	for(int i=head[u];i;i=nxt[i]){
		int v=go[i];
		if(v==fa)continue;
		dfs(v,u);
		root[u]=merge(root[u],root[v],1,n);
	}
	ans[u]=Max[root[u]]-dep[u];
}
signed main(){
	n=read();
	for(int i=1;i<n;i++)add(read(),read());
	dfs(1,0);
	for(int i=1;i<=n;i++)printf("%d
",ans[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/naruto-mzx/p/13154478.html