codeforces - 600E Lomsat gelral

题目链接:Lomsat gelral


题目大意:就是求任意一个子树的出现最多的颜色的值,如果出现次数一样则累加。


然后就是一道树上启发式合并的裸题啦!

我们每次用重链维护信息,往上传递,其他信息暴力更新即可。


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,c[N],cnt[N],mx,sum,res[N],sz[N],son[N],skip;
int head[N],nex[N<<1],to[N<<1],tot;
inline void add(int a,int b){
	to[++tot]=b; nex[tot]=head[a]; head[a]=tot;
}
void dfs(int x,int fa){
	sz[x]=1;
	for(int i=head[x];i;i=nex[i]){
		if(to[i]==fa)	continue;
		dfs(to[i],x);	sz[x]+=sz[to[i]];
		if(sz[to[i]]>sz[son[x]])	son[x]=to[i];
	}
}
void updata(int x,int fa,int k){
	cnt[c[x]]+=k;
	if(x>0&&cnt[c[x]]>mx)	mx=cnt[c[x]],sum=c[x];
	else if(x>0&&cnt[c[x]]==mx)	sum+=c[x];
	for(int i=head[x];i;i=nex[i]){
		if(to[i]!=fa&&to[i]!=skip)	updata(to[i],x,k);
	}
}
void solve(int x,int fa,int k){
	for(int i=head[x];i;i=nex[i]){
		if(to[i]!=fa&&to[i]!=son[x])	solve(to[i],x,0);
	}
	if(son[x])	solve(son[x],x,1),skip=son[x];
	updata(x,fa,1);	res[x]=sum; skip=0;
	if(!k)	updata(x,fa,-1),mx=sum=0;
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++)	cin>>c[i];
	for(int i=1;i<n;i++){
		int a,b;	cin>>a>>b;	add(a,b);	add(b,a);
	}
	dfs(1,0);	solve(1,0,0);
	for(int i=1;i<=n;i++)	cout<<res[i]<<" ";puts("");
	return 0;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-07 13:35
虽然不怎么光彩,经过这件事,可能我真的要去认同“面试八股文早该淘汰!不会用AI作弊的程序员=新时代文盲!”这句话了
HellowordX:Ai的出现是解放劳动力的,不是用来破坏公平竞争环境的,这样下去,轻则取消所有线上面试,严重了会影响整个行业对所有人产生影响,企业会拉高入职考核各种离谱考核会层出不穷
你找工作的时候用AI吗?
点赞 评论 收藏
分享
06-11 17:39
门头沟学院 Java
小呆呆的大鼻涕:卧槽,用户彻底怒了
点赞 评论 收藏
分享
鬼迹人途:你去投一投尚游游戏,服务器一面,第一个图算法,做完了给你一个策略题,你给出方案他就提出低概率问题,答不上当场给你挂
点赞 评论 收藏
分享
07-08 13:48
门头沟学院 C++
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务