码迷,mamicode.com
首页 > 其他好文 > 详细

CF 600 E Lomsat gelral —— 树上启发式合并

时间:2018-09-22 01:03:18      阅读:271      评论:0      收藏:0      [点我收藏+]

标签:string   keep   http   csdn   oid   big   blank   omsa   contest   

题目:http://codeforces.com/contest/600/problem/E

看博客:https://blog.csdn.net/blue_kid/article/details/82192641

https://blog.csdn.net/clove_unique/article/details/60772212

还是不太明白复杂度...

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const xn=1e5+5;
int n,c[xn],hd[xn],ct,to[xn<<1],nxt[xn<<1],cnt[xn],siz[xn],son[xn],mx,big;
ll ans[xn],sum;
void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
int rd()
{
    int ret=0,f=1; char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=0; ch=getchar();}
    while(ch>=0&&ch<=9)ret=(ret<<3)+(ret<<1)+ch-0,ch=getchar();
    return f?ret:-ret;
}
void dfs(int x,int fa)
{
    siz[x]=1;
    for(int i=hd[x],u;i;i=nxt[i])
    {
        if((u=to[i])==fa)continue;
        dfs(u,x); siz[x]+=siz[u];
        if(siz[u]>siz[son[x]])son[x]=u;
    }
}
void add(int x,int fa,int v)
{
    cnt[c[x]]+=v;
    if(cnt[c[x]]>mx)sum=c[x],mx=cnt[c[x]];
    else if(cnt[c[x]]==mx)sum+=c[x];
    for(int i=hd[x],u;i;i=nxt[i])
        if((u=to[i])!=fa&&u!=big)add(u,x,v);
}
void dfs2(int x,int fa,int keep)
{
    for(int i=hd[x],u;i;i=nxt[i])
        if((u=to[i])!=fa&&u!=son[x])dfs2(u,x,0);
    if(son[x])dfs2(son[x],x,1),big=son[x];
    add(x,fa,1); big=0;
    ans[x]=sum;
    if(!keep)add(x,fa,-1),mx=sum=0;//=0!
}
int main()
{
    n=rd();
    for(int i=1;i<=n;i++)c[i]=rd();
    for(int i=1,x,y;i<n;i++)
    {
        x=rd(); y=rd();
        add(x,y); add(y,x);
    }
    dfs(1,0); dfs2(1,0,0);
    for(int i=1;i<=n;i++)printf("%I64d ",ans[i]);
    return 0;
}

 

CF 600 E Lomsat gelral —— 树上启发式合并

标签:string   keep   http   csdn   oid   big   blank   omsa   contest   

原文地址:https://www.cnblogs.com/Zinn/p/9688708.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!