【CodeForces】600 E. Lomsat gelral (dsu on tree)
【题目】E. Lomsat gelral
【题意】给定n个点的树,1为根,每个点有一种颜色ci,一种颜色占领一棵子树当且仅当子树内没有颜色的出现次数超过它,求n个答案——每棵子树的占领颜色的编号和Σci(一棵子树可能有多种占领颜色)。1<=n,ci<=10^5。
【算法】dsu on tree
【题解】入门题,讲一下dsu on tree算法。
一、dsu on tree的适用范围:①子树询问,②支持数组上的快速信息加,③不带修。(注意不需要支持信息删除,只需要能清空信息)
如果写暴力的时候,每个点需要开一个O(n)的数组,然后要从下往上的合并数组,那么dsu on tree就可以帮你把复杂度降低到O(n log n)。
二、dsu on tree的过程:
①递归处理轻儿子,不保存信息。
②递归处理重儿子,保存信息。
③暴力加入该子树处理重儿子子树外的所有点的信息,得到该子树的答案。
④如果父边是轻边,扫描整棵子树清空信息。(操作必须和点数相关才能保证复杂度)
三、dsu on tree的复杂度证明:
算法思想是先处理轻儿子并且不保存,然后处理重儿子并且保存信息,这样每个点暴力扫描子树都不会包含重儿子子树。
轻重链剖分的特点是每个点到根至多经过log n条轻边,所以一般只要支持快速处理重链。(这个证明可以考虑最左端的底层节点,每跳一次轻边其右儿子都必须翻倍)
dsu on tree中每个点只会在其到根的路径中的所有轻边被遍历到1次,所以每个点的复杂度是O(log n)的。
总复杂度O(n log n)。
对于本题,需要支持快速信息加,记a[i]表示颜色i的出现次数,mx表示最多出现次数,sum表示答案,加的时候更新一下,清空的时候直接mx=sum=0即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
int c[maxn],first[maxn],tot,sz[maxn],w[maxn],a[maxn],n,mx;
long long ans[maxn],sum;
bool vis[maxn];
struct edge{int v,from;}e[maxn*];
void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
void predfs(int x,int fa){
sz[x]=;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa){
predfs(e[i].v,x);
sz[x]+=sz[e[i].v];
if(sz[e[i].v]>sz[w[x]])w[x]=e[i].v;
}
}
void add(int x,int fa,int k){
a[c[x]]+=k;
if(k>){
if(a[c[x]]>mx){
mx=a[c[x]];sum=c[x];
}
else if(a[c[x]]==mx)sum+=c[x];
}
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!vis[e[i].v])add(e[i].v,x,k);
}
void dfs(int x,int fa,int k){
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&e[i].v!=w[x])dfs(e[i].v,x,);
if(w[x])dfs(w[x],x,),vis[w[x]]=;
add(x,fa,);
if(w[x])vis[w[x]]=;
ans[x]=sum;
if(!k)add(x,fa,-),mx=sum=;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&c[i]);
for(int i=;i<n;i++){
int u,v;scanf("%d%d",&u,&v);
insert(u,v);insert(v,u);
}
predfs(,);dfs(,,);
for(int i=;i<=n;i++)printf("%lld ",ans[i]);
return ;
}
【CodeForces】600 E. Lomsat gelral (dsu on tree)的更多相关文章
- Codeforces 600E. Lomsat gelral(Dsu on tree学习)
题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...
- Codeforces.600E.Lomsat gelral(dsu on tree)
题目链接 dsu on tree详见这. \(Description\) 给定一棵树.求以每个点为根的子树中,出现次数最多的颜色的和. \(Solution\) dsu on tree模板题. 用\( ...
- 【CodeForces】914 H. Ember and Storm's Tree Game 动态规划+排列组合
[题目]H. Ember and Storm's Tree Game [题意]Zsnuoの博客 [算法]动态规划+排列组合 [题解]题目本身其实并不难,但是大量干扰因素让题目显得很神秘. 参考:Zsn ...
- 【CodeForces】915 F. Imbalance Value of a Tree 并查集
[题目]F. Imbalance Value of a Tree [题意]给定n个点的带点权树,求所有路径极差的和.n,ai<=10^6 [算法]并查集 [题解]先计算最大值的和,按点权从小到大 ...
- cf600E. Lomsat gelral(dsu on tree)
题意 题目链接 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 Sol dsu on tree的裸题. 一会儿好好总结总结qwq #include<bits/stdc++.h> ...
- CF 600E. Lomsat gelral(dsu on tree)
解题思路 \(dsu\) \(on\) \(tree\)的模板题.暴力而优雅的算法,轻儿子的信息暴力清空,重儿子的信息保留,时间复杂度\(O(nlogn)\) 代码 #include<iostr ...
- codeforces600E. Lomsat gelral(dsu on tree)
dsu on tree先分轻重儿子先处理轻边,再处理重儿子再加上轻儿子的答案 #include<iostream> #include<cstdio> #include<q ...
- Educational Codeforces Round 2 E. Lomsat gelral(dsu)
题目链接 题意:给你一棵以1为根n个点的树,问你以i为根的子树的众数和是多少 思路:dsu是一种优化暴力的手段 首先进行轻重链剖分 然后只记录重链的信息 轻链的信息就直接暴力查找 经过证明这样复杂度可 ...
- 【Codeforces】Round #491 (Div. 2) 总结
[Codeforces]Round #491 (Div. 2) 总结 这次尴尬了,D题fst,E没有做出来.... 不过还好,rating只掉了30,总体来说比较不稳,下次加油 A:If at fir ...
随机推荐
- HDU 2106 母猪的故事
http://acm.hdu.edu.cn/showproblem.php?pid=2160 Problem Description 话说现在猪肉价格这么贵,著名的ACBoy 0068 也开始了养猪生 ...
- [转帖漫画]什么是 MD5 算法?---摘要算法 具体算法 一直搞不清楚
漫画:什么是 MD5 算法? 2017-10-05 20:16 来源:伯乐专栏作者/玻璃猫,微信公众号 - 梦见 好文投稿, 请点击 → 这里了解详情 梦见 摘要哈希生成的正确姿势是什么样呢?分三步: ...
- vue-cli配置axios
1. npm install axios --save 2. npm install @type/axios --save-dev(使用ts编写的需要此声明文件,升级的axios好像不需要了,已经自带 ...
- C语言版kafka消费者代码运行时异常kafka receive failed disconnected
https://github.com/edenhill/librdkafka/wiki/Broker-version-compatibility如果使用了broker版本是0.8的话, 在运行例程时需 ...
- IE显示对象不支持此属性或方法 的解决方法
用C# 编写的ActiveX控件, 调试时,在世界之窗浏览器里能正确显示,但是不能和JS交互,也没有传说中的错误信息框出现,查了很多文档,后来想问题是不是出在浏览器上,换在IE8里调试,点击交互按钮, ...
- Be the Winner HDU - 2509(反博弈。。这样叫应该没错吧。。)
就是 好几堆苹果 每堆苹果排成一条线 可以任意从每堆拿苹果 如果一堆苹果里拿了之后 则有两种情况 1.从不是边缘拿 拿完这一堆变成两堆 2.从边缘拿 拿完还是一堆 题目还要求 谁 ...
- 【BZOJ4869】【SHOI2017】相逢是问候
Description BZOJ传送门 Solution 这题涉及到指数嵌套堆叠,可能可以用欧拉函数解决. 试想一个数\(a_i\)经过\(k\)次操作后会变成什么? \[ k个c\;\; \begi ...
- java线程池赏析
1.线程池的顶级接口(Executor) 线程池的顶级接口(jdk > 1.5).仅仅定义了方法execute(Runnable). 该方法接收一个Runnable实例,用来执行一个任务,该任务 ...
- 解题:洛谷2257 YY的GCD
题面 初见莫比乌斯反演 有一个套路是关于GCD的反演经常设$f(d)=\sum_{gcd(i,j)==d},g(d)=\sum_{d|gcd(i,j)}$,然后推推推 $\sum\limits_{i= ...
- D. Huge Strings Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combined)
http://codeforces.com/contest/868/problem/D 优化:两个串合并 原有状态+ 第一个串的尾部&第二个串的头部的状态 串变为第一个串的头部&第二个 ...