题意

一棵树有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)的更多相关文章

  1. CF600E Lomsat gelral(dsu on tree)

    dsu on tree跟冰茶祭有什么关系啊喂 dsu on tree的模板题 思想与解题过程 类似树链剖分的思路 先统计轻儿子的贡献,再统计重儿子的贡献,得出当前节点的答案后再减去轻儿子对答案的贡献 ...

  2. cf600E. Lomsat gelral(dsu on tree)

    题意 题目链接 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 Sol dsu on tree的裸题. 一会儿好好总结总结qwq #include<bits/stdc++.h> ...

  3. CF600E Lomsat gelral——线段树合并/dsu on tree

    题目描述 一棵树有$n$个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 这个题意是真的窒息...具体意思是说,每个节点有一个颜色,你要找的是每个子树中颜色的众数 ...

  4. CF600E Lomsat gelral 和 CF741D Dokhtar-kosh paths

    Lomsat gelral 一棵以\(1\)为根的树有\(n\)个结点,每个结点都有一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号(若有数量一样的,则求编号和). \(n \le 10^ ...

  5. [CF600E]Lomsat gelral

    题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 线段树合并板子题,没啥难度,注意开long long 不过这题$dsu$ $on$ $tre ...

  6. CF600E Lomsat gelral 树上启发式合并

    题目描述 有一棵 \(n\) 个结点的以 \(1\) 号结点为根的有根树. 每个结点都有一个颜色,颜色是以编号表示的, \(i\) 号结点的颜色编号为 \(c_i\)​. 如果一种颜色在以 \(x\) ...

  7. CF600E Lomsat gelral 【线段树合并】

    题目链接 CF600E 题解 容易想到就是线段树合并,维护每个权值区间出现的最大值以及最大值位置之和即可 对于每个节点合并一下两个子节点的信息 要注意叶子节点信息的合并和非叶节点信息的合并是不一样的 ...

  8. CF600E Lomsat gelral (启发式合并)

    You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour. Let's cal ...

  9. CF600E Lomsat gelral (dfs序+莫队)

    题面 题解 看到网上写了很多DSU和线段树合并的题解,笔者第一次做也是用的线段树合并,但在原题赛的时候却怕线段树合并调不出来,于是就用了更好想更好调的莫队. 这里笔者就说说莫队怎么做吧. 我们可以通过 ...

随机推荐

  1. Dota2APP--第一天

    从今天开始,下定决心自己独立开发一个有关于Dota2的APP,因为非常喜欢这个游戏恰好自己又是做iOS移动开发的所以萌生了这个想法.希望可以坚持下去,有喜欢dota2的朋友也可以提点建议. 一.项目的 ...

  2. 火焰图定位dbproxy问题

    https://blog.csdn.net/oujiangping/article/details/78580450 https://blog.csdn.net/gatieme/article/det ...

  3. 2016级算法第六次上机-E.Bamboo之吃我一拳

    Bamboo之吃我一拳 分析 当两个点的距离<=d时,才可以出拳,想要使得满足出拳条件的点对最少但不为0 寻找最近点对距离,得到的最近距离能够使得可以出拳的组数最少,因为除了最近点对外其他组合均 ...

  4. JMeter知识点整理

  5. ThreadLocal系列(二)-InheritableThreadLocal的使用及原理解析

    ThreadLocal系列之InheritableThreadLocal的使用及原理解析(源码基于java8) 上一篇:ThreadLocal系列(一)-ThreadLocal的使用及原理解析 下一篇 ...

  6. Access network

    1       State transfering A•Mobility:开机-搜寻PLMN/CELL来发现自己在网络中的位置•Attach request•Auth request•Auth res ...

  7. [转] Scala 的集合类型与数组操作

    [From] https://blog.csdn.net/gongxifacai_believe/article/details/81916659 版权声明:本文为博主原创文章,转载请注明出处. ht ...

  8. java使用freemarker生成word文档

    1.原料 开源jar包freemarker.eclipse.一份模板word文档 2.首先设计模板word文档 一般,通过程序输出的word文档的格式是固定的,例如建立一个表格,将表格的标题写好,表格 ...

  9. 【Guava】基于guava的重试组件Guava-Retryer

    一.使用场景 在日常开发中,我们经常会遇到需要调用外部服务和接口的场景.外部服务对于调用者来说一般都是不可靠的,尤其是在网络环境比较差的情况下,网络抖动很容易导致请求超时等异常情况,这时候就需要使用失 ...

  10. hibernate基本配置show_sql、sql_format

    show_sql是否打印生成的sql语句: <property name="show_sql">false</property> sql_format,格式 ...