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; }