【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 ...
随机推荐
- PAT 1147 Heaps
https://pintia.cn/problem-sets/994805342720868352/problems/994805342821531648 In computer science, a ...
- jdbc -- 001 -- 一般方式创建数据库连接(oracle/mysql)
连接数据库步骤: 1. 注册驱动(只做一次) 2. 建立连接(Connection) 3. 创建执行SQL的语句(Statement) 4. 执行语句 5. 处理执行结果(ResultSet) 6. ...
- 一文总结之Redis
目录 Redis 目标 Redis简介 什么是Redis 特性 Redis当前应用情况 安装 基本使用 键 exists判断键存在性.del删除键.type键类型 expire key的时效性设置 基 ...
- HDU4240_Route Redundancy
题目很简单.给一个有向图,求两点间的最大流量与任意一条路中的最大流量的比值. 最大流不说了,求出单条流量最大的路径可以用类似Spfa的方法来搞,保存到达当前点的最大流量,一直往下更新即可. 召唤代码君 ...
- 关于 Source Engine 2007 网络通信的分析
最近在写自己的游戏引擎,主要是参考Quake和GoldSrc和SourceEngine2007,其中SourceEngine2007代码比较新一些. 对比了这几个引擎的代码,前两者代码比较简单,基于C ...
- Visual Categorization with Bags of Keypoints
1.Introduction and backgrounds 作为本周的论文之一,这是一篇bag of features的基本文章之一,主要了解其中的基本思路,以及用到的基本技术,尽量使得细节更加清楚 ...
- Eclipse – Java.Lang.OutOfMemoryError: Java Heap Space(转)
In Eclipse IDE, if your program is consuming a lot of memory (loading big data) like this : List< ...
- bzoj 3667 Rabin-Miller算法
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #i ...
- [NOI2012]美食节——费用流(带权二分图匹配)+动态加边
题目描述 小M发现,美食节共有n种不同的菜品.每次点餐,每个同学可以选择其中的一个菜品.总共有m个厨师来制作这些菜品.当所有的同学点餐结束后,菜品的制作任务就会分配给每个厨师.然后每个厨师就会同时开始 ...
- Python之旅:数据类型、字符编码、文件处理
一 引子 1 什么是数据? x=10,10是我们要存储的数据 2 为何数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3 数据类型 以下每个类型都是有详细介绍链接的 ...