[Codeforces600E] Lomsat gelral(树上启发式合并)
[Codeforces600E] Lomsat gelral(树上启发式合并)
题面
给出一棵N个点的树,求其所有子树内出现次数最多的颜色编号和。如果多种颜色出现次数相同,那么编号都要算进答案
N≤100000
分析
树上启发式合并,用map记录颜色出现次数,合并的时候更新最多的出现次数和编号和。
注意合并时的下标问题。当我们merge(x,y)的时候,由于是启发式合并,s[x]可能会并到s[y]去,如果我们直接查询s[x],就查不到真正的答案。所以要再建立一个数组id[x],记录x的map合并之后到了哪里
代码
//树上启发式合并
#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<cstring>
#include<vector>
#define maxn 100000
using namespace std;
int n;
int c[maxn+5];
vector<int>E[maxn+5];
int id[maxn+5];
//当我们merge(x,y)的时候,由于是启发式合并,s[x]可能会并到s[y]去
//然后直接查询s[x]就炸了,所以id[x]就是记录x的map合并之后到了哪里
map<int,int>s[maxn+5];
int ans_max[maxn+5];//最多的出现次数
long long ans_cnt[maxn+5];//编号和
long long res[maxn+5];
void merge(int x,int y){
if(s[id[x]].size()<s[id[y]].size()){
swap(id[x],id[y]);
}
int u=id[x],v=id[y];
for(auto it : s[v]){
int val=it.first;
int cnt=it.second;
s[u][val]+=cnt;
if(s[u][val]>ans_max[u]){
ans_max[u]=s[u][val];
ans_cnt[u]=val;
}else if(s[u][val]==ans_max[u]){
ans_cnt[u]+=val;
}
}
}
void dfs(int x,int fa){
for(int y : E[x]){
if(y!=fa){
dfs(y,x);
merge(x,y);
}
}
res[x]=ans_cnt[id[x]];
}
int main(){
int u,v;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
id[i]=i;
s[i][c[i]]=1;
ans_max[i]=1;
ans_cnt[i]=c[i];
}
for(int i=1;i<n;i++){
scanf("%d %d",&u,&v);
E[u].push_back(v);
E[v].push_back(u);
}
dfs(1,0);
for(int i=1;i<=n;i++){
printf("%I64d ",res[i]);
}
}
[Codeforces600E] Lomsat gelral(树上启发式合并)的更多相关文章
- CF EDU - E. Lomsat gelral 树上启发式合并
学习:http://codeforces.com/blog/entry/44351 E. Lomsat gelral 题意: 给定一个以1为根节点的树,每个节点都有一个颜色,问每个节点的子树中,颜色最 ...
- CF 600 E Lomsat gelral —— 树上启发式合并
题目:http://codeforces.com/contest/600/problem/E 看博客:https://blog.csdn.net/blue_kid/article/details/82 ...
- CF600E Lomsat gelral 树上启发式合并
题目描述 有一棵 \(n\) 个结点的以 \(1\) 号结点为根的有根树. 每个结点都有一个颜色,颜色是以编号表示的, \(i\) 号结点的颜色编号为 \(c_i\). 如果一种颜色在以 \(x\) ...
- 【CF600E】Lomsat gelral——树上启发式合并
(题面来自luogu) 题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. ci <= n <= 1e5 裸题.统计时先扫一遍得到出 ...
- CodeForces600E Lomsat gelral 线段树合并
从树上启发式合并搜出来的题 然而看着好像线段树合并就能解决??? 那么就用线段树合并解决吧 维护\(max, sum\)表示值域区间中的一个数出现次数的最大值以及所有众数的和即可 复杂度\(O(n \ ...
- Codeforces 600 E. Lomsat gelral (dfs启发式合并map)
题目链接:http://codeforces.com/contest/600/problem/E 给你一棵树,告诉你每个节点的颜色,问你以每个节点为根的子树中出现颜色次数最多的颜色编号和是多少. 最容 ...
- Codeforces 600E - Lomsat gelral(树上启发式合并)
600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...
- 【学习笔记/题解】树上启发式合并/CF600E Lomsat gelral
题目戳我 \(\text{Solution:}\) 树上启发式合并,是对普通暴力的一种优化. 考虑本题,最暴力的做法显然是暴力统计每一次的子树,为了避免其他子树影响,每次统计完子树都需要清空其信息. ...
- 【CF600E】Lomset gelral 题解(树上启发式合并)
题目链接 题目大意:给出一颗含有$n$个结点的树,每个节点有一个颜色.求树中每个子树最多的颜色的编号和. ------------------------- 树上启发式合并(dsu on tree). ...
随机推荐
- 什么是Azkaban?
Azkaban是什么 Azkaban是由Linkedin开源的做批量工作流任务的调度器.在一个工作流内按照特定的顺序运行一组工作和流程.Azkaban定义了一种KV文件格式来建立任务之间的相互依赖关系 ...
- mybatis resultMap之collection聚集两种实现方式
最近做得项目用到了MyBatis处理一对多的映射关系,下面的两个方法中用到了集合的嵌套查询方法,下面仔细学习一下这两种方式 聚集元素用来处理"一对多"的关系.需要指定映射的Java ...
- iOS App中 使用 OpenSSL 库
转自:http://blog.csdn.net/kmyhy/article/details/6534067 在你的 iOS App中 使用 OpenSSL 库 ——译自x2on的“Tutorial: ...
- 09.Linux系统由于不正常关机导致的分区问题
问题:Error:UNEXPECTED INCONSISTENCY: RUN fsck MANUALLY Give root password for maintenance ------------ ...
- Sass-@extend
Sass 中的 @extend 是用来扩展选择器或占位符.比如: .error { border: 1px #f00; background-color: #fdd; } .error.intrusi ...
- pandas 新增数据列(直接赋值、apply,assign、分条件赋值)
# pandas新增数据列(直接赋值.apply.assign.分条件赋值) # pandas在进行数据分析时,经常需要按照一定条件创建新的数据列,然后进行进一步分析 # 1 直接赋值 # 2 df. ...
- 装饰器模式-Decerator
一.定义 装饰器模式又叫做包装模式(Wrapper).装饰器模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 在以下情况下应该使用装饰器模式: 1.需要扩展一个类的功能,或给一个类增 ...
- centos7标准版命令界面和图形界面相互切换
1.root登陆终端 2.输入命令 vi /etc/inittab ,查看两种界面的启动模式: 3.退出vi模式,,输入命令systemctl get-default 查看当前系统启动模式:我的是命令 ...
- linux运维、架构之路-linux用户管理
一. linux系统用户分类 1.分类 ①超级用户:root,UID为0 ②普通用户:UID是500-65535的用户 ③虚拟用户:UID在1-499,一般不能登录,满足文件或服务启动的需要,/sbi ...
- 06 IntelliJ IDEA构建多模块项目