点分治

点分治 & 点分树 的一些理解。

点分治

什么是点分治

点分治,是树分治的一种。

树分治包括了点分治,边分治,链分治。

点分治主要处理两点间路径信息的问题。

点分治怎么用

拿最基本的问题入手,给你一棵树,让你统计树上距离为 \(k\) 的点对个数。

形式的说 \(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[dist(i,j)=k]\)

\(naive\ sol1\)

当我们知道一个端点 \(i\) 的时候,我们可以 \(\mathcal{O(n)}\) 的求出该点的贡献,每个点都 \(\mathcal{O(n)}\) 计算,总复杂度\(\mathcal{O(n^2)}\)

\(naive\ sol2\)

考虑分治,随机选一个点 \(u\) ,把点 \(u\) 删掉,算出剩下的每个连通块的子问题和。同时把经过点 \(u\) 的链的答案统计出来。

由于分治,复杂度为 \(\mathcal{O(dep\times n)}\) ,\(dep\) 为分治层数。

\(right\ sol\)

发现让分治层数最小,本质上是让每次分治时产生的最大的连通块最小。因为此时分治层数可以看成最大的连通块变成 \(1\) 的次数。

发现这个定义本质上就是找重心。在重心心处分治。

由于中心的性质,每一次分割后产生的最大的连通块 \(maxsz\leq\lceil\frac{sz}{2}\rceil\)

所以 \(dep\) 一定是 \(O(\log_{2}n)\) 级别的。

至于合并,也就一个 \(O(sz)\) 解决的问题。


点分树

什么是点分树

假如当前重心为 \(u\) 我们把删去 \(u\) 之后产生的新重心 \(v_{1,2,\cdots,k}\)\(u\) 连边。

不难发现最终形态是一棵树。

我们把这棵树称作点分树。

点分树有什么用

观察点分治,我们每次合并答案都只在该连通块的重心处合并该连通块内的贡献。

所以假如谈一个点 \(u\) 的贡献,那么他只可能在 \(u\) 点,使 \(u\) 点单独成为连通块所删除的重心 \(v\),使 \(v\) 点所在连通块被从一个大连通块剥离出来而删的重心 \(z\),and so on 。

发现产生贡献的重心,全都在 点分树中 \(u\) 到根的路径上。

所以我们统计答案相当于在统计一条链,而这个链的长度是 \(\mathcal{O(\log_2n)}\) 级别的。

所以我们可以通过点分树来维护一些更难于直接记录的信息,以及一些修改操作。

对于点分治,点分树,有一点需要注意。

为什么点分治是对的?原因就在于,通过在重心时对链的合并,本质上就已经完成枚举树上的每一条路径了。

所以点分治本质上和那个 \(\mathcal{O(n^2)}\) 的暴力时一样在枚举路径的。

所以在看到有树上问题问路径的一些情况,不妨考虑一下点分治。

练手推荐

震波

捉迷藏

Qtree4

开店

树上游戏

本人实力有限,都是模板题了/kk


点分治
https://proton-z.github.io/2021/02/13/point-divide-simple-thoughts/
作者
Imitators
发布于
2021年2月13日
许可协议