久未放晴的天空,依旧留着你|

TulipeNoire

园龄:1年10个月粉丝:18关注:17

树分治学习笔记

前言

既然序列可以分治,那么树也可以分治。树上的分治可以分为点分治与边分治。

点分治

边分治主要用于处理树上路径问题。

考虑一个分治的过程:选中一棵树的根,计算经过根的路径的贡献,然后以其子结点为根对子树递归地计算贡献。容易发现,在构造数据下这种算法的复杂度是可以达到 O(n2) 的,原因在于递归的层数可能太深了。如果不使用子结点,而是使用子树的重心,那么每一次子树的大小都会减半,递归层数降到了 O(logn) 级别。而每一层的点数是 O(n) 的,所以总时间复杂度变成了 O(nklogn),其中 k 是统计贡献的复杂度。

然而从理论到实现还是需要一定距离的,因为点分治需要很多细节。

拓展:点分序列

我们可以将每次计算贡献函数里的点都加进一个序列,那么我们就得到了有 O(nlogn) 个数,称为点分序列。我们不妨在上面维护一些信息,比如说这个点到它当时的根的路径产生的贡献。这样你就通过 O(nlogn) 个区间来表示整棵树的路径信息了。可以用来做超级钢琴类似的东西。

点分树

有了点分治的基础,我们就可以方便定义点分树了。点分树的构造方式就是每一个重心向下一层递归中心连有向边,形成一棵有根树。它有两个重要的性质:

  • 它的深度是 O(logn) 级别的。

  • 对于 uv,它们在点分树上的 lca 在原树 uv 的路径上。

由第二个性质我们可以得到 dist(u,lca)+dist(v,lca)=dist(u,v)。其中 dist 是原树上距离,而 lca 是点分树上 lca

有了这个重要的性质,就可以直接暴力跳祖先维护了。

本文作者:TulipeNoire

本文链接:https://www.cnblogs.com/TulipeNoire/p/Divide_and_Counquer_on_Tree.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   TulipeNoire  阅读(40)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起