十几天前看到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序使用莫队有异曲同工之妙,莫队也要求修改的复杂度很低


应用

  1. 优秀的dfs序莫队替代品,复杂度\(\sqrt{n} \rightarrow logn\)
  2. 结合点分治的思想可以做一些有根树上的路径统计问题

模板题

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]【学习笔记】的更多相关文章

  1. dsu on tree学习笔记

    前言 一次模拟赛的\(T3\):传送门 只会\(O(n^2)\)的我就\(gg\)了,并且对于题解提供的\(\text{dsu on tree}\)的做法一脸懵逼. 看网上的其他大佬写的笔记,我自己画 ...

  2. dsu on tree 学习笔记

    这是一个黑科技,考虑树链剖分后,每个点只会在轻重链之间转化\(log\)次. 考虑暴力是怎么写的,每次枚举一个点,再暴力把子树全部扫一边. \(dsu\ on\ tree.\)的思想就是保留重儿子不清 ...

  3. 珂朵莉树(Chtholly Tree)学习笔记

    珂朵莉树(Chtholly Tree)学习笔记 珂朵莉树原理 其原理在于运用一颗树(set,treap,splay......)其中要求所有元素有序,并且支持基本的操作(删除,添加,查找......) ...

  4. Codeforces 600E. Lomsat gelral(Dsu on tree学习)

    题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...

  5. Link Cut Tree学习笔记

    从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...

  6. 矩阵树定理(Matrix Tree)学习笔记

    如果不谈证明,稍微有点线代基础的人都可以在两分钟内学完所有相关内容.. 行列式随便找本线代书看一下基本性质就好了. 学习资源: https://www.cnblogs.com/candy99/p/64 ...

  7. k-d tree 学习笔记

    以下是一些奇怪的链接有兴趣的可以看看: https://blog.sengxian.com/algorithms/k-dimensional-tree http://zgjkt.blog.uoj.ac ...

  8. splay tree 学习笔记

    首先感谢litble的精彩讲解,原文博客: litble的小天地 在学完二叉平衡树后,发现这是只是一个不稳定的垃圾玩意,真正实用的应有Treap.AVL.Splay这样的查找树.于是最近刚学了学了点S ...

  9. LSM Tree 学习笔记——本质是将随机的写放在内存里形成有序的小memtable,然后定期合并成大的table flush到磁盘

    The Sorted String Table (SSTable) is one of the most popular outputs for storing, processing, and ex ...

  10. LSM Tree 学习笔记——MemTable通常用 SkipList 来实现

    最近发现很多数据库都使用了 LSM Tree 的存储模型,包括 LevelDB,HBase,Google BigTable,Cassandra,InfluxDB 等.之前还没有留意这么设计的原因,最近 ...

随机推荐

  1. hdu_1711Number Sequence(kmp)

    Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. Linux shell编程命令-Linux基础环境命令学习笔记

    1.正则表达式 1)^开始 *前一个字符重复0次以上 + 1次以上 ? 0次或者1次 . 一个任意字符(.*连用) {m,n} m到n次 [0-9][a-z] 任意数字或字母 $结束字符 2)sed和 ...

  3. JXLS 2.4.0系列教程(一)——最简单的模板导出

    Java中实现excel根据模板导出数据的方法有很多,一般简单的可以通过操作POI进行.还可以使用一些工具很轻松的实现模板导出.这些工具现在还在维护,而且做得比较好的国内的有easyPOI,国外的就是 ...

  4. docker运行dubbo-admin

    一:简介 dubbo-admin是dubbo框架的管理平台. 二: 创建继续镜像 Dockerfile FROM fangjipu/jdk8:8 RUN yum -y install epel-rel ...

  5. JavaScript八张思维导图—编程实践

    JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...

  6. Navicat连接阿里云Mysql遇到的的坑

    连上去那一刻,心态真是起飞了

  7. Spark算子--mapPartitions和mapPartitionsWithIndex

    mapPartitions--Transformation类算子 代码示例 result   mapPartitionsWithIndex--Transformation类算子 代码示例 result ...

  8. sqlite效率探测

    在编译后当然就是使用sqlite,贸贸然去测试了一下创建数据库,插入数据,仅几条数据,发现,真不错的数据库,后来把数据量提高到10000的 时候,发现,怎么这么慢,后来自己都受不了,网上一查,原来是如 ...

  9. SVN的安装和配置

    SVN为程序开发团队常用的代码管理,版本控制软件:下面我们来介绍TortoiseSVN的安装,和其服务器的搭建:(下面为windows 64位系统下的搭建) 闲来无事,就在本地搭建了一个SVN环境,网 ...

  10. JQ滚动特效

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...