dsu on tree(CF600E Lomsat gelral)
题意
一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和。
dsu on tree
用来解决子树问题
好像不能带修改??
暴力做这个题,就是每次扫一遍子树统计答案
时间\(O(n^2)\)
或者会高级的数据结构解决
空间,编程难度是个挑战
然而\(dsu \ on \ tree\)树上启发式合并则是一个好方法
它通过增加对重儿子子树信息的利用来提高效率
流程:
递归轻儿子
递归重儿子
统计答案
如果该点为它父亲的重儿子,保存信息
否则删除信息
复杂度分析:
每个点被扫到的次数只有它到根的路径上轻边的次数*\(2\)次
也就是\(log\)次
那么总复杂度为空间\(O(n)\),时间\(O(nlogn)\)
该题代码
# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
}
const int maxn(1e5 + 5);
int n, first[maxn], cnt, col[maxn], size[maxn], son[maxn], vis[maxn], num[maxn], mx;
ll sum[maxn], ans[maxn];
struct Edge{
int to, next;
} edge[maxn << 1];
IL void Add(RG int u, RG int v){
edge[cnt] = (Edge){v, first[u]}, first[u] = cnt++;
}
IL void Dfs(RG int u, RG int ff){
size[u] = 1;
for(RG int e = first[u]; e != -1; e = edge[e].next){
RG int v = edge[e].to;
if(v != ff){
Dfs(v, u);
size[u] += size[v];
if(size[v] > size[son[u]]) son[u] = v;
}
}
}
IL void Update(RG int u, RG int ff, RG int val){
sum[num[col[u]]] -= col[u];
num[col[u]] += val;
sum[num[col[u]]] += col[u];
if(val > 0) mx = max(mx, num[col[u]]);
else while(mx && !sum[mx]) --mx;
for(RG int e = first[u]; e != -1; e = edge[e].next)
if(edge[e].to != ff && !vis[edge[e].to]) Update(edge[e].to, u, val);
}
IL void Solve(RG int u, RG int ff, RG int op){
size[u] = 1;
for(RG int e = first[u]; e != -1; e = edge[e].next)
if(edge[e].to != ff && edge[e].to != son[u]) Solve(edge[e].to, u, 0);
if(son[u]) Solve(son[u], u, 1), vis[son[u]] = 1;
Update(u, ff, 1), vis[son[u]] = 0;
ans[u] = sum[mx];
if(!op) Update(u, ff, -1);
}
int main(){
n = Input();
for(RG int i = 1; i <= n; ++i) col[i] = Input(), first[i] = -1;
for(RG int i = 1; i < n; ++i){
RG int u = Input(), v = Input();
Add(u, v), Add(v, u);
}
Dfs(1, 0), Solve(1, 0, 1);
for(RG int i = 1; i <= n; ++i) printf("%lld ", ans[i]);
return 0;
}
dsu on tree(CF600E Lomsat gelral)的更多相关文章
- CF600E Lomsat gelral(dsu on tree)
dsu on tree跟冰茶祭有什么关系啊喂 dsu on tree的模板题 思想与解题过程 类似树链剖分的思路 先统计轻儿子的贡献,再统计重儿子的贡献,得出当前节点的答案后再减去轻儿子对答案的贡献 ...
- cf600E. Lomsat gelral(dsu on tree)
题意 题目链接 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 Sol dsu on tree的裸题. 一会儿好好总结总结qwq #include<bits/stdc++.h> ...
- CF600E Lomsat gelral——线段树合并/dsu on tree
题目描述 一棵树有$n$个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 这个题意是真的窒息...具体意思是说,每个节点有一个颜色,你要找的是每个子树中颜色的众数 ...
- CF600E Lomsat gelral 和 CF741D Dokhtar-kosh paths
Lomsat gelral 一棵以\(1\)为根的树有\(n\)个结点,每个结点都有一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号(若有数量一样的,则求编号和). \(n \le 10^ ...
- [CF600E]Lomsat gelral
题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 线段树合并板子题,没啥难度,注意开long long 不过这题$dsu$ $on$ $tre ...
- CF600E Lomsat gelral 树上启发式合并
题目描述 有一棵 \(n\) 个结点的以 \(1\) 号结点为根的有根树. 每个结点都有一个颜色,颜色是以编号表示的, \(i\) 号结点的颜色编号为 \(c_i\). 如果一种颜色在以 \(x\) ...
- CF600E Lomsat gelral 【线段树合并】
题目链接 CF600E 题解 容易想到就是线段树合并,维护每个权值区间出现的最大值以及最大值位置之和即可 对于每个节点合并一下两个子节点的信息 要注意叶子节点信息的合并和非叶节点信息的合并是不一样的 ...
- CF600E Lomsat gelral (启发式合并)
You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour. Let's cal ...
- CF600E Lomsat gelral (dfs序+莫队)
题面 题解 看到网上写了很多DSU和线段树合并的题解,笔者第一次做也是用的线段树合并,但在原题赛的时候却怕线段树合并调不出来,于是就用了更好想更好调的莫队. 这里笔者就说说莫队怎么做吧. 我们可以通过 ...
随机推荐
- Java_锁Synchronized
锁(synchronized):既然线程之间是并发执行,就必然会有资源冲突的时候,如果不加以限制,很可能会出现死锁现象,这时就需要锁来对线程获取资源的限制程序中,可以给类,方法,代码块加锁.1.方法锁 ...
- Laravel5.5 使用第三方Vendor添加注册验证码
Laravel5系列的验证码添加通用,使用第三方验证码即可完美实现.这里记录下具体步骤吧,以备不时之需. 第一步:使用composer 安装 验证码库 composer require mews/ca ...
- maven项目在eclipse启动报错:java.lang.ClassNotFoundException
问题: 用eclipse创建maven项目的时候,pom.xml中相关的依赖jar已经导入进去,还会报java.lang.ClassNotFoundException的错误,提示找不到相关的jar包, ...
- Docker 拷贝文件
1.从容器里面拷文件到宿主机? 答:在宿主机里面执行以下命令 docker cp 容器名:要拷贝的文件在容器里面的路径 要拷贝到宿主机的相应路径 示例: 假设容器名为testtomcat, ...
- css中字体单位px,pt,em,百分比之间的区别和用法
px 即像素,一般国内网站使用较多,默认大小是16px; pt 印刷行业常用单位 em 相对单位,相对父元素属性的单位 ,一般用于移动端布局 rem 结合相对定位和绝对定位的优势,相对根元素htm ...
- Javac的命令
关于命令,还可以查看<Java 7程序设计>一书后面的附录A As per javac source docs, there are 4 kinds of options: standar ...
- linux mint 19安装 kvm 软件包
1 我的处理器是2700x 首先安装cpu检测 sudo apt-get install cpu-checker 2 查看cpu内核 egrep -c '(vmx|svm)' /proc/cpuinf ...
- 机器学习 损失函数(Loss/Error Function)、代价函数(Cost Function)和目标函数(Objective function)
损失函数(Loss/Error Function): 计算单个训练集的误差,例如:欧氏距离,交叉熵,对比损失,合页损失 代价函数(Cost Function): 计算整个训练集所有损失之和的平均值 至 ...
- Java Servlet 缺点
1.web.xml配置比较多 2.servlet具有容器依赖性(tomcat没有启动,就没有用)
- PHP之mb_convert_case使用
mb_convert_case (PHP 4 >= 4.3.0, PHP 5, PHP 7) mb_convert_case - Perform case folding on a string ...