dsu on tree 模板题目(CF600E Lomsat gelral)
题解:
dsu on tree
对于结点i来说,步骤为:
递归轻儿子,不保留贡献。
递归重儿子,保留贡献。
统计当前结点及所有轻儿子的贡献。
拿个样例来解释算法的流程
比如说样例2:
如图所示,有多个结点的大小相同,重儿子应该是节点数目最多的那个子节点,那么我们假设1号结点的重儿子是4号结点。
递归轻儿子顺序与输入顺序有关系。
因为空间有限,我们无法把所有结点的状态给存起来,所以用的是1个cnt数组。
假设我们计算14号结点后要去计算15号结点,但是这两个结点用的是同一个cnt数组,那么当我们计算完14号结点的答案后,我们要清空14号结点对cnt数组造成的影响后,才可以去计算15号结点。
同样的方法当我们把2 、 14 、 3 、 15这四个结点计算完后,我们再去计算重儿子4号结点。
但是与轻儿子不同的是,当我们计算完4号重儿子结点的信息后,cnt数组可以不用清空。
为什么?
当我们把1号结点所有的子节点的答案都计算完成后,那就意味着2-15号结点的答案都已经有了,那么还差1号结点没有计算,我们计算1号结点的时候需要遍历1号结点包括的所有结点(也就是2-15号结点),那假设我们没有把4号结点(重儿子)以及他子树的信息清空,那么我们是不是就可以少遍历4 、11 、12、 13这四个结点,只需要去遍历2,5,6,7,14,3,8,9,10,15这些结点。
从而减少了时间复杂度,(玄学)
case2输入:
15
1 2 3 1 2 3 3 1 1 3 2 2 1 2 3
1 2
1 3
1 4
1 14
1 15
2 5
2 6
2 7
3 8
3 9
3 10
4 11
4 12
4 13
case2输出:
6 5 4 3 2 3 3 1 1 3 2 2 1 2 3
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
#define int long long
struct node{int to,next;
}edge[maxn];int head[maxn];
int tot=0;
void add(int u,int v){edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
}
int col[maxn];
int sz[maxn],son[maxn];
void dfs1(int x,int fa){ //重链剖分找重儿子sz[x]=1;for(int i=head[x];~i;i=edge[i].next){int v=edge[i].to;if(v==fa) continue;dfs1(v,x);sz[x]+=sz[v];if(sz[v]>sz[son[x]]) son[x]=v;}
}
int flag,cnt[maxn]; //cnt表示当前统计结点以及他子树颜色的数量 flag用来标记重儿子
int imax,sum; //imax用来记录当前结点最大值 sum记录答案(比如说有很多个颜色数目相同的颜色,答案就是颜色的编号和)
void count(int u,int fa,int val){cnt[col[u]]+=val;if(cnt[col[u]]>imax){imax=max(cnt[col[u]],imax);sum=col[u];} else if(cnt[col[u]]==imax){ //有多个颜色数目相同的颜色sum+=col[u];}for(int i=head[u];~i;i=edge[i].next){ //暴力统计int v=edge[i].to;if(v==fa||v==flag) continue;count(v,u,val);}
}
int ans[maxn];
void dsu(int u,int fa,bool keep){for(int i=head[u];~i;i=edge[i].next){int v=edge[i].to;if(v==fa||v==son[u]) continue;dsu(v,u, false);}if(son[u]){ //如果是重儿子,keep=1,这样就不会删除重儿子上的信息了dsu(son[u],u,true);flag=son[u];}count(u,fa,1); //暴力统计flag=0;ans[u]=sum; //记录答案if(!keep){ //如果不是重儿子 ,暴力删除轻儿子上面的信息count(u,fa,-1);sum=imax=0;}
}signed main(){ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);memset(head,-1,sizeof(head));int n;cin>>n;for(int i=1;i<=n;i++) cin>>col[i];for(int i=0;i<n-1;i++){int u,v;cin>>u>>v;add(u,v);add(v,u);}dfs1(1,0);//cout<<son[1]<<endl;dsu(1,0,0);for(int i=1;i<=n;i++){cout<<ans[i]<<" ";}return 0;
}
dsu on tree 模板题目(CF600E Lomsat gelral)相关推荐
- dsu on tree入门
先瞎扯几句 说起来我跟这个算法好像还有很深的渊源呢qwq.当时在学业水平考试的考场上,题目都做完了不会做,于是开始xjb出题.突然我想到这么一个题 看起来好像很可做的样子,然而直到考试完我都只想出来一 ...
- [dsu on tree]树上启发式合并总结(算法思想及模板附例题练习)
文章目录 前言 树上启发式合并 引入 算法思想 时间复杂度 模板 练习 例题:CF600E Lomsat gelral solution code CF208E Blood Cousins solut ...
- Lomsat gelral
cf600E. Lomsat gelral 题意:给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 板子题 #include<iostream> #include<cstd ...
- Codeforces 600E Lomsat gelral (树上启发式合并)
题目链接 Lomsat gelral 占坑--等深入理解了再来补题解-- #include <bits/stdc++.h>using namespace std;#define rep(i ...
- 【CF 600E】Lomsat gelral(树上启发式合并, dsu on tree, 静态链分治,模板题)
Algorithm 名称:树上启发式合并, dsu on tree, 静态链分治 用处:一般用来解决一类不带修改的子树查询问题 核心思想为:利用重链剖分的性质优化子树贡献的计算. 前置知识:启发式合并 ...
- 【算法讲20:Dsu on Tree】树上数颜色 | Lomsat gelral
[算法讲20:Dsu on Tree] [例一:树上数颜色] · 暴力做法 · · 考虑优化 · ⌈ D s u o n T r e e ⌋ \lceil Dsu\ on\ Tree\rfloor ⌈ ...
- Codeforces 600E. Lomsat gelral(Dsu on tree学习)
题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...
- dsu on tree(Educational Codeforces Round 2: E. Lomsat gelral)
题意: 一棵n个节点的树,每个节点都有一种颜色,如果颜色c在以u为根的子树中出现的次数大于等于一半,那么这个颜色就是u节点的支配色, 因为是大于等于,所以一个节点的支配色可能不止一种,求出每个节点的支 ...
- 数据结构之线段树合并——永无乡,Lomsat gelral,Tree Rotations,Tree Rotations Escape Through Leaf
文章目录 [HNOI2012]永无乡 Lomsat gelral 「POI2011 R2 Day2」旋转树木 Tree Rotations Escape Through Leaf 线段树合并与 fhq ...
最新文章
- [原创]微软拼音输入法2007(含64位版)
- 跨链Cosmos(1) 网络拓扑
- 开源游戏服务器端框架Firefly正式将GFirefly整合
- 新版ipados可以编辑C语言吗,iPadOS新增了五个有用的功能,看你需不需要
- 10分钟搭建完成人脸通行系统 百度『乘风』人脸智能化平台了解一下
- 防火墙设置导致服务器站点打开,服务器、网站、环境配置全正常网站打不开原来是系统防火墙造成的...
- 返回一个循环数组中最大子数组的和
- 【转】“你不适合做程序员”
- 线程+urllib下载互联网图片的一个示例
- android修改机型cpu,mac,androidid....
- 通过CSS美化Web页面
- 常用测试用例设计方法4-场景法
- 基金常用的分析指标:跟踪误差率、信息比率、夏普比率到底是什么意思?
- 联想ghost重装系统_史上最全的重装ghost系统错误解决方法大全
- 怎么把html在别人电脑上打开文件,html文件怎么打开?电脑用浏览器打开html文件的方法...
- CentOS7使用mount命令来挂载CDROM
- R语言可视化——熵曲线
- windows系统镜像修复计算机,电脑映像损坏怎么修复_windows提示损坏的映像怎么处理...
- easyui tabs 的href和content属性
- MySQL快速插入亿级数据