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和线段树合并的题解,笔者第一次做也是用的线段树合并,但在原题赛的时候却怕线段树合并调不出来,于是就用了更好想更好调的莫队. 这里笔者就说说莫队怎么做吧. 我们可以通过 ...
随机推荐
- Dota2APP--第一天
从今天开始,下定决心自己独立开发一个有关于Dota2的APP,因为非常喜欢这个游戏恰好自己又是做iOS移动开发的所以萌生了这个想法.希望可以坚持下去,有喜欢dota2的朋友也可以提点建议. 一.项目的 ...
- 火焰图定位dbproxy问题
https://blog.csdn.net/oujiangping/article/details/78580450 https://blog.csdn.net/gatieme/article/det ...
- 2016级算法第六次上机-E.Bamboo之吃我一拳
Bamboo之吃我一拳 分析 当两个点的距离<=d时,才可以出拳,想要使得满足出拳条件的点对最少但不为0 寻找最近点对距离,得到的最近距离能够使得可以出拳的组数最少,因为除了最近点对外其他组合均 ...
- JMeter知识点整理
- ThreadLocal系列(二)-InheritableThreadLocal的使用及原理解析
ThreadLocal系列之InheritableThreadLocal的使用及原理解析(源码基于java8) 上一篇:ThreadLocal系列(一)-ThreadLocal的使用及原理解析 下一篇 ...
- Access network
1 State transfering A•Mobility:开机-搜寻PLMN/CELL来发现自己在网络中的位置•Attach request•Auth request•Auth res ...
- [转] Scala 的集合类型与数组操作
[From] https://blog.csdn.net/gongxifacai_believe/article/details/81916659 版权声明:本文为博主原创文章,转载请注明出处. ht ...
- java使用freemarker生成word文档
1.原料 开源jar包freemarker.eclipse.一份模板word文档 2.首先设计模板word文档 一般,通过程序输出的word文档的格式是固定的,例如建立一个表格,将表格的标题写好,表格 ...
- 【Guava】基于guava的重试组件Guava-Retryer
一.使用场景 在日常开发中,我们经常会遇到需要调用外部服务和接口的场景.外部服务对于调用者来说一般都是不可靠的,尤其是在网络环境比较差的情况下,网络抖动很容易导致请求超时等异常情况,这时候就需要使用失 ...
- hibernate基本配置show_sql、sql_format
show_sql是否打印生成的sql语句: <property name="show_sql">false</property> sql_format,格式 ...