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\n",ans[i]);
return 0;
}
标签:ch,Dominant,val,CF1009F,int,luogu,while,ls,getchar 来源: https://www.cnblogs.com/naruto-mzx/p/13154478.html