【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 ...
随机推荐
- Mysql Group Replication 简介及单主模式组复制配置【转】
一 Mysql Group Replication简介 Mysql Group Replication(MGR)是一个全新的高可用和高扩张的MySQL集群服务. 高一致性,基于原生复制及p ...
- MicrosoftFixit50688 [Windows7事件ID10,WMI错误的解决方法
Windows7事件记录中有如下错误提示: "Event filter with query "SELECT * FROM __InstanceModificationEve ...
- NeuralEnhance: 提高图像分辨率的深度学习模型
NeuralEnhance是使用深度学习训练的提高图像分辨率的模型,使用Python开发,项目地址:https://github.com/alexjc/neural-enhance. 貌似很多电影都有 ...
- javascript获取当前日期和时间
){ ){ _time = year+"-"+month+"-"+date+" "+hour+":"+minu+&quo ...
- IE Only的userData
上次我们提到了本地存储的一个方式,那就是Cookie,不过遗憾的是Cookie保存的数据量非常小,更详细的可以参考<在 Internet Explorer 中的 cookie 的数字和大小限制& ...
- FlatBuffers初探
我第一次知道FlatBuffers是因为Facebook写的这篇Android的技术博客文章.它主要介绍了FlatBuffers对比JSON的优势,以及Facebook Android App应用了F ...
- BZOJ5099 POI2018Pionek
假设确定了最终所得向量的方向,则应该选择所有在该方向上投影为正的向量.按极角序排序后这显然是一段连续区间.最终向量方向很难枚举,但对于某个向量,在其上投影为正的向量与其夹角范围是(-π/2,π/2), ...
- linux 批量更改文件名 rename 命令
rename 的典型应用: # rename $1 $2 $3# $1: 要被取代的關鍵字# $2: 新的關鍵字# $3: 檔名符合這個規則的才取代 # 把 IMG001.jpg, IMG002.jp ...
- 【比赛】NOIP2017 列队
一直忘了发,现在赶快补 用权值线段树维护有人的位置,动态开点省空间 多加的人用个vector存下来就可以了 #include<bits/stdc++.h> #define ui unsig ...
- 浅谈Tarjan算法及思想
在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连 ...