标签:bsp get mes style std 产生 else href col
题意:给你一个树,每个节点有一个颜色,求每个节点出现次数最大颜色编号和。
/* CF600E 启发式合并 复杂度 n*(log(n) */ #include<bits/stdc++.h> using namespace std; const int N=1e5+5; int son[N],col[N],head[N],size[N]; long long cnt[N],ans[N]; struct edge{int v,next;}e[N<<2]; int ecnt,n,maxc,thisson; long long thissum; void init(){ memset(head,-1,sizeof head); memset(son,0,sizeof son); maxc=ecnt=thisson=thissum=0; } void add(int u,int v){ e[ecnt].v=v;e[ecnt].next=head[u];head[u]=ecnt++; } void dfs_size(int u,int fa){//剖分树链 size[u]=1; for(int i=head[u];~i;i=e[i].next){ int v=e[i].v; if(v==fa)continue; dfs_size(v,u); size[u]+=size[v]; if(size[v]>size[son[u]])son[u]=v; } } void Count(int u,int fa,int val){//累积或删除贡献 cnt[col[u]]+=val; if(cnt[col[u]]>maxc){ maxc=cnt[col[u]]; thissum=col[u]; } else if(cnt[col[u]]==maxc)thissum+=col[u]; for(int i=head[u];~i;i=e[i].next){ int v=e[i].v; if(v==fa||v==thisson)continue; Count(v,u,val); } } void dfs_ans(int u,int fa,bool keep){//统计每个点的答案,保留或者不保留贡献 for(int i=head[u];~i;i=e[i].next){ int v=e[i].v; if(v==fa||v==son[u])continue; dfs_ans(v,u,false); } if(son[u]){ dfs_ans(son[u],u,true); thisson=son[u]; } Count(u,fa,1); thisson=0; ans[u]=thissum; if(!keep){ Count(u,fa,-1); thissum=maxc=0; } } int main(){ scanf("%d",&n); init(); for(int i=1;i<=n;i++)scanf("%d",&col[i]); for(int i=1,u,v;i<n;i++){ scanf("%d %d",&u,&v); add(u,v);add(v,u); } dfs_size(1,-1); dfs_ans(1,-1,0); for(int i=1;i<=n;i++)printf("%I64d ",ans[i]); return 0; }
标签:bsp get mes style std 产生 else href col
原文地址:https://www.cnblogs.com/littlerita/p/12791208.html