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

 

posted @ 2019-10-24 14:24  nervending  阅读(137)  评论(0编辑  收藏  举报