题意:给你一棵有 nn 个点的树 (n\leq10^5)(n≤105) ,树上每个节点都有一种颜色 ci(ci\leq n)ci(ci≤n) ,让你求每个点子树出现最多的颜色的 颜色编号 的和

 

线段树合并可以维护子树的所有线段树之和 

 

权值线段维护一下出现最多的数字即可

codeforces 600E  线段树合并_子树codeforces 600E  线段树合并_权值_02
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=2e6+10;

ll sum[N<<2],t[N<<2],anss[N];
int lson[N<<2],rson[N<<2],ncnt,pos,head[N],c[N],n,T[N];

void up(int pos)
{
    if(sum[lson[pos]]>sum[rson[pos]])
    {
        sum[pos]=sum[lson[pos]];
        t[pos]=t[lson[pos]];
    }
    else if(sum[lson[pos]]<sum[rson[pos]])
    {
        sum[pos]=sum[rson[pos]];
        t[pos]=t[rson[pos]];
    }
    else if(sum[lson[pos]]==sum[rson[pos]])
    {
        sum[pos]=sum[lson[pos]];
        t[pos]=t[lson[pos]]+t[rson[pos]];
    }
}

void upnode(int x,int l,int r,int &pos)
{
    if(!pos)pos=++ncnt;
    if(l==r){sum[pos]+=1;t[pos]=l;return ;}
    int m=(l+r)>>1;
    if(x<=m)upnode(x,l,m,lson[pos]);
    else upnode(x,m+1,r,rson[pos]);
    up(pos);
}
int Merge(int a,int b,int l,int r)
{
    if(!a)return b;
    if(!b)return a;
    if(l==r)
    {
        sum[a]+=sum[b];
        t[a]=l;
        return a;
    }
    int m=(l+r)>>1;
    lson[a]=Merge(lson[a],lson[b],l,m);
    rson[a]=Merge(rson[a],rson[b],m+1,r);
    up(a);return a;
}

struct Edge{int to,nex;}edge[N];
void add(int a,int b){edge[++pos]=(Edge){b,head[a]};head[a]=pos;}

void dfs(int x,int fa)
{
    for(int i=head[x];i;i=edge[i].nex)
    {
        int v=edge[i].to;
        if(v==fa)continue;
        dfs(v,x);//注意 这里是 先更新 然后再合并
        Merge(T[x],T[v],1,1e5);
    }
    upnode(c[x],1,100000,T[x]);
    anss[x]=t[T[x]];
}

int main()
{
    cin>>n;
    rep(i,1,n)scanf("%d",&c[i]),ncnt++,T[i]=i;
    rep(i,1,n-1)
    {
        int x,y;scanf("%d%d",&x,&y);
        add(x,y);add(y,x);

    }
    dfs(1,0);
    rep(i,1,n)
    printf("%lld ",anss[i]);
    return 0;
}
View Code