[dsu on tree]【学习笔记】
十几天前看到zyf2000发过关于这个的题目的Blog, 今天终于去学习了一下
[Codeforces原文链接](http://codeforces.com/blog/entry/44351#comment-332425)
dsu on tree
简介
我也不清楚dsu是什么的英文缩写...
好吧是Disjoint Set Union 并查集2333
就像是树上的启发式合并
用到了\(heavy-light\ decomposition\)树链剖分
把轻边子树的信息合并到重链上的点里
因为每次都是先dfs轻儿子再dfs重儿子,只有重儿子子树的贡献保留,所以可以保证dfs到每颗子树时当前全局维护的信息不会有别的子树里的,和莫队很像
算法过程
find the BigChild of each vertex
dfs(u, fa, keep)
dfs(LightChild, u, 0)
dfs(BigChild, u, 1), big[BigChild] = 1
update(u, fa, 1) //calculate the contribution of u's LightChild's SubTree
update the ans of u
big[BigChild] = 0
if keep == 0
update(u, fa, -1) //remove the contributino of u's SubTree
update(u, fa, val)
calculate u's information
update(v : (u, v) and !big[v], u, val)
先递归计算轻儿子子树,递归结束时消除他们的贡献
再递归计算重儿子子树,保留他的贡献
再计算当前子树中所有轻子树的贡献
更新答案
如果当前子树是父节点的轻子树,消除当前子树的贡献
复杂度分析
显然只有遇到轻边才会把自己的信息合并到父节点
树链剖分后每个点到根的路径上有\(logn\)条轻边和\(lgon\)条重链
一个点的信息只会向上合并\(logn\)次
如果一个点的信息修改是\(O(1)\)的,那么总复杂度就是\(O(nlogn)\)
从这里我们可以发现和对dfs序使用莫队有异曲同工之妙,莫队也要求修改的复杂度很低
应用
- 优秀的dfs序莫队替代品,复杂度\(\sqrt{n} \rightarrow logn\)
- 结合点分治的思想可以做一些有根树上的路径统计问题
模板题
CF600E. Lomsat gelral
题意:询问每颗子树中出现次数最多的颜色们编号和
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define pii pair<int, ll>
#define MP make_pair
#define fir first
#define sec second
const int N=1e5+5;
int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
}
int n, a[N];
struct edge{int v, ne;}e[N<<1];
int cnt, h[N];
inline void ins(int u, int v) {
e[++cnt]=(edge){v, h[u]}; h[u]=cnt;
e[++cnt]=(edge){u, h[v]}; h[v]=cnt;
}
int size[N], mx[N], big[N];
void dfs(int u, int fa) {
size[u]=1;
for(int i=h[u];i;i=e[i].ne)
if(e[i].v != fa) {
dfs(e[i].v, u);
size[u] += size[e[i].v];
if(size[e[i].v] > size[mx[u]]) mx[u] = e[i].v;
}
}
int cou[N], Max; ll ans[N];
pii f[N];
void update(int u, int fa, int val) {
int &c = cou[a[u]];
f[c].fir --; f[c].sec -= a[u];
c += val;
f[c].fir ++; f[c].sec += a[u];
if(val==1) Max = max(Max, c);
else if(!f[Max].fir) Max--;
for(int i=h[u];i;i=e[i].ne)
if(e[i].v != fa && !big[e[i].v]) update(e[i].v, u, val);
}
void dfs(int u, int fa, int keep) {
for(int i=h[u];i;i=e[i].ne)
if(e[i].v != fa && e[i].v != mx[u]) dfs(e[i].v, u, 0);
if(mx[u]) dfs(mx[u], u, 1), big[mx[u]] = 1;
update(u, fa, 1);
ans[u] = f[Max].sec;
big[mx[u]] = 0;
if(!keep) update(u, fa, -1);
}
int main() {
//freopen("in","r",stdin);
n=read();
for(int i=1; i<=n; i++) a[i]=read();
for(int i=1; i<n; i++) ins(read(), read());
dfs(1, 0);
dfs(1, 0, 1);
for(int i=1; i<=n; i++) printf("%I64d ",ans[i]);
}
[dsu on tree]【学习笔记】的更多相关文章
- dsu on tree学习笔记
前言 一次模拟赛的\(T3\):传送门 只会\(O(n^2)\)的我就\(gg\)了,并且对于题解提供的\(\text{dsu on tree}\)的做法一脸懵逼. 看网上的其他大佬写的笔记,我自己画 ...
- dsu on tree 学习笔记
这是一个黑科技,考虑树链剖分后,每个点只会在轻重链之间转化\(log\)次. 考虑暴力是怎么写的,每次枚举一个点,再暴力把子树全部扫一边. \(dsu\ on\ tree.\)的思想就是保留重儿子不清 ...
- 珂朵莉树(Chtholly Tree)学习笔记
珂朵莉树(Chtholly Tree)学习笔记 珂朵莉树原理 其原理在于运用一颗树(set,treap,splay......)其中要求所有元素有序,并且支持基本的操作(删除,添加,查找......) ...
- Codeforces 600E. Lomsat gelral(Dsu on tree学习)
题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...
- Link Cut Tree学习笔记
从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...
- 矩阵树定理(Matrix Tree)学习笔记
如果不谈证明,稍微有点线代基础的人都可以在两分钟内学完所有相关内容.. 行列式随便找本线代书看一下基本性质就好了. 学习资源: https://www.cnblogs.com/candy99/p/64 ...
- k-d tree 学习笔记
以下是一些奇怪的链接有兴趣的可以看看: https://blog.sengxian.com/algorithms/k-dimensional-tree http://zgjkt.blog.uoj.ac ...
- splay tree 学习笔记
首先感谢litble的精彩讲解,原文博客: litble的小天地 在学完二叉平衡树后,发现这是只是一个不稳定的垃圾玩意,真正实用的应有Treap.AVL.Splay这样的查找树.于是最近刚学了学了点S ...
- LSM Tree 学习笔记——本质是将随机的写放在内存里形成有序的小memtable,然后定期合并成大的table flush到磁盘
The Sorted String Table (SSTable) is one of the most popular outputs for storing, processing, and ex ...
- LSM Tree 学习笔记——MemTable通常用 SkipList 来实现
最近发现很多数据库都使用了 LSM Tree 的存储模型,包括 LevelDB,HBase,Google BigTable,Cassandra,InfluxDB 等.之前还没有留意这么设计的原因,最近 ...
随机推荐
- lombok使用基础教程
前言 lombok是一个编译级别的插件,它可以在项目编译的时候生成一些代码.在很多工具类的项目中都有这个功能.比如dagger. 通俗的说,lombok可以通过注解来标示生成getter settte ...
- 互联网App应用程序测试流程及测试总结
互联网App应用程序测试流程及测试总结 1. APP测试基本流程 1.1流程图 仍然为测试环境 Pass 1.2测试周期 测试周期可按项目的开发周期来确定测试时间,一般测试时间为两三周(即15个工作日 ...
- ECharts 环形饼图 动态获取json数据
ECharts 环形饼图 动态获取json数据 效果图如下: 一.html部分 <div id="secondPieChart" style="width:100 ...
- Spring的IOC分析(一)
我们学习Spring之前需要对23种java的设计模式的9种有一定的理解,设计模式为了解耦,Spring也是在解耦的方向上设计的,所以设计模式要理解一下,它当中用到了很多. 单例模式(写法很多钟,7种 ...
- angular4 中自定义pagination组件
你用Angular 吗? 一.介绍 一个基于angular4 开发的可以分页的组件.组件的好处就是可以复用,复用.....作为一个前端码农,开始的分页功能实现是我用jquery写的,其他同事用的时候都 ...
- Java的栈和队列
package com.ipmotor.sm.db;import java.util.LinkedList;import java.util.Queue;import java.util.Stack; ...
- [one day one question] Vue数组变更不能触发刷新
问题描述:Vue数组变更不能触发刷新,特别是数组的每个元素都是对象的时候,对象中某个属性的值发生变化,根本无法触发Vue的dom刷新,这怎么破? 解决方案:this.$set(array, index ...
- 2017-06-23(chmod whoami chown)
文件权限设定 chmod u-x newfile chmod u-x,g+w newfile chmod a=rwx newfile [mode=421] r = 4 , w=2, x=1 chmod ...
- eclipse报错资料备份
一. eclipse中初始化控件出错 在添加 TextView myTextView=(TextView)this.findViewById(R.id.myTextView); Button myBu ...
- python_如何派生内置不可变类型并修改实例化行为
案例: 我们想要自定义新类型的元组,对传入的可迭代对象我们只保留其中的int类型并且值大于0的元素,如下: [1, -2, 'xxx', 7, [1, 'oo'], 9] >> (1, ...