【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 ...
随机推荐
- Navicat for MySQL笔记1
1.MySQL数据库的基本操作 A.系统数据库 安装MySQL数据库服务器后,自带的数据库. B.用户数据库 用户根据实际需求所创建的数据库. C.数据库对象 表.视图.存储过程.函数.触发器以及事件 ...
- PAT 1024 科学计数法
https://pintia.cn/problem-sets/994805260223102976/problems/994805297229447168 科学计数法是科学家用来表示很大或很小的数字的 ...
- Delphi控件-复合控件【转】
复合控件复合控件是Delphi控件中非常重要的一种控件,复合控件就是将两个或两个以上的控件重新组合成一个新的控件.例如TspinEdit.TlabeledEdit.TDBNavigator等就是复合控 ...
- Java 使用 Dbutils 工具类库 操作mysql
Dbutils 官网http://commons.apache.org/proper/commons-dbutils/ 结合我个人写的JDBCUtils 写的 Dbutils 的使用demo . JD ...
- ognl用法 取变量时候 需要在变量前面加上# 取字符串需要用单引号包裹字符串
- P4329 [COCI2006-2007#1] Bond
题意翻译 有n 个人去执行n 个任务,每个人执行每个任务有不同的成功率,每个人只能执行一个任务,求所有任务都执行的总的成功率. 输入第一行,一个整数n (1≤n≤20 ),表示人数兼任务数.接下来n ...
- git 复位出现If no other git process is currently running, this probably means a git process crashed in this repo
复位到A节点的时候点了取消(终止),又去复位另外个节点,结果每次不管复位哪个都会报这个错误 fatal: Unable to create 'XXXXXXXXX' : File exists. If ...
- 【刷题】BZOJ 3591 最长上升子序列
Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个整数,表示这个最长上升 ...
- [bzoj1875][SDOI2009] HH去散步 [dp+矩阵快速幂]
题面 传送门 正文 其实就是让你求有多少条长度为t的路径,但是有一个特殊条件:不能走过一条边以后又立刻反着走一次(如果两次经过同意条边中间隔了别的边是可以的) 如果没有这个特殊条件,我们很容易想到dp ...
- AptanaStudio3+PHP程序远程调试的方法和步骤
php是执行在服务器上的脚本程序,通常调试bug,直接在浏览器页面就可以打印出错误信息,凭此基本能解决所有bug,但是有时候,可以说大多数时候,php会直接处理客户端的请求,作为数据接口传递数据,没有 ...