codeforces 600E dfs+线段树合并
给你一棵有 n 个点的树
树上每个节点都有一种颜色 让你求每个点其子树出现最多的颜色,的节点编号
可以有多个最大值,一起计算.
裸的线段树合并,边dfs边合并就行了,最后把父亲放进去
#include<bits/stdc++.h>
#define ll long long
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(int ii=b;ii>=a;--ii)
#define forn(i,x,g,e) for(int i=g[x];i;i=e[i].next)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define fi first
#define se second
#define mp make_pair
#define pii pair<ll,ll>
#define all(x) x.begin(),x.end()
#define show(x) cout<<#x<<"="<<x<<endl
#define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
#define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show5(v,w,x,y,z) cout<<#v<<"="<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define showa(x,a,b) cout<<#x<<": ";rep(i,a,b) cout<<x[i]<<' ';cout<<endl
using namespace std;//head
const int maxn=1e5+10,maxm=2e6+10;
const ll INF=0x3f3f3f3f,mod=1e9+7;
int casn,m,k,n;
int a[maxn],cnt;
vector<int> g[maxn];
int root[maxn];
ll ans[maxn];
class dsegtree{public:
#define nd node[now]
#define ndl node[node[now].son[0]]
#define ndr node[node[now].son[1]]
struct dsegnode {
int son[2],cnt,id;
ll ans;
}node[maxn*50];
void pushup(int now){
if(ndl.cnt>ndr.cnt){
nd.cnt=ndl.cnt;
nd.id=ndl.id;
nd.ans=ndl.ans;
}else if(ndr.cnt>ndl.cnt){
nd.cnt=ndr.cnt;
nd.id=ndr.id;
nd.ans=ndr.ans;
}else {
nd.cnt=ndr.cnt;
nd.id=ndr.id;
nd.ans=ndr.ans+ndl.ans;
}
}
void update(int l,int r,int pos,int &now){
if(!now) now=++cnt;
if(l==r){
nd.id=nd.ans=l;
nd.cnt+=1;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) update(l,mid,pos,nd.son[0]);
else update(mid+1,r,pos,nd.son[1]);
pushup(now);
}
int merge(int now,int b,int l,int r){
if(!now||!b) return now^b;
if(l==r){
nd.id=nd.ans=l;
nd.cnt+=node[b].cnt;
return now;
}
nd.son[0]=merge(nd.son[0],node[b].son[0],l,(l+r)/2);
nd.son[1]=merge(nd.son[1],node[b].son[1],(l+r)/2+1,r);
pushup(now);
return now;
}
}tree;
void dfs(int now,int fa){
for(int to:g[now]){
if(to==fa) continue;
dfs(to,now);
tree.merge(root[now],root[to],1,1e5);
}
tree.update(1,1e5,a[now],root[now]);
ans[now]=tree.node[root[now]].ans;
}
int main() {IO;
cin>>n;
rep(i,1,n){
cin>>a[i];
root[i]=i;
}
cnt=n;
rep(i,2,n){
int a,b;cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
dfs(1,0);
rep(i,1,n) cout<<ans[i]<<' ';
return 0;
}

浙公网安备 33010602011771号