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和线段树合并的题解,笔者第一次做也是用的线段树合并,但在原题赛的时候却怕线段树合并调不出来,于是就用了更好想更好调的莫队. 这里笔者就说说莫队怎么做吧. 我们可以通过 ...
随机推荐
- Tsung安装指南
1. 所需要软件包unixODBC-2.2.14.tar.gzotp_src_R13B02-1.tar.gztsung-1.3.1.tar.gzTemplate-Toolkit-2.22.tar.gz ...
- 浅谈Android选项卡(三)
上一节介绍了TabActivity的简单用法,但是现在的Api中已经不建议使用了,建议使用Fragment来替代以上的功能,下面介绍下使用Fragment和ViewPager的结合使用. http:/ ...
- java_I/O字符流
I/O流(Stream) INPUT:输入流,从文件里读OUPUT:输出流,写内容到文件 IO流分为:字符流和字节流 字符流:处理纯文本文件. 字节流:处理可以所有文件. 字符输出流测试: @Test ...
- P5242 [USACO19FEB]Cow Dating
题目链接 题意分析 首先我们可以得出计算公式 \[s_i=\prod_{k=1}^i(1-p_k)\] \[f_i=\sum_{k=1}^i\frac{p_k}{1-p_k}\] 那么 \[ans(i ...
- POJ 2192
#include <iostream> #include <string> #define MAXN 500 using namespace std; bool dp[MAXN ...
- FlowPortal-BPM——离线审批(邮箱审批)配置
一.将系统文件复制到安装目录下 二.以管理员身份运行bat安装程序 三.开启邮件离线审批服务 四.创建数据库表(JAVA数据库 或 .Net数据库) 五.配置config文件(发件箱.收件箱.错误问题 ...
- go 语言学习 1
Go语言命名 Go语言关键字 1.Go语言有25个关键字: 2.关键字用途: var :用于变量的声明const :用于常量的声明type :用于声明类型func :用于声明函数和方法package ...
- 问题 K: 周期串plus
问题 K: 周期串plus 时间限制: 1 Sec 内存限制: 128 MB提交: 682 解决: 237[提交] [状态] [命题人:外部导入] 题目描述 如果一个字符串可以由某个长度为k的字符 ...
- Mac OS 10.12后Caps lock(大写键)无法使用的解决办法
▲打开设置中的键盘选项,并切换至输入源选项标签, ▲取消勾选“使用大写锁定键来回切换“美国英文””, ▲这时再按下Caps lock即可正常使用大小写切换. ▲Update:目前macOS 10.12 ...
- html5+js+.Net的即时多人聊天
今天看了下websocket的知识,了解到这是html5新增的特性,主要用于实时web的通信.之前客户端获取服务端的数据,是通过客户端发出请求,服务端进行响应的模式,或者通过ajax每 ...