树分治学习笔记
前言
既然序列可以分治,那么树也可以分治。树上的分治可以分为点分治与边分治。
点分治
边分治主要用于处理树上路径问题。
考虑一个分治的过程:选中一棵树的根,计算经过根的路径的贡献,然后以其子结点为根对子树递归地计算贡献。容易发现,在构造数据下这种算法的复杂度是可以达到 的,原因在于递归的层数可能太深了。如果不使用子结点,而是使用子树的重心,那么每一次子树的大小都会减半,递归层数降到了 级别。而每一层的点数是 的,所以总时间复杂度变成了 ,其中 是统计贡献的复杂度。
然而从理论到实现还是需要一定距离的,因为点分治需要很多细节。
拓展:点分序列
我们可以将每次计算贡献函数里的点都加进一个序列,那么我们就得到了有 个数,称为点分序列。我们不妨在上面维护一些信息,比如说这个点到它当时的根的路径产生的贡献。这样你就通过 个区间来表示整棵树的路径信息了。可以用来做超级钢琴类似的东西。
点分树
有了点分治的基础,我们就可以方便定义点分树了。点分树的构造方式就是每一个重心向下一层递归中心连有向边,形成一棵有根树。它有两个重要的性质:
-
它的深度是 级别的。
-
对于 和 ,它们在点分树上的 在原树 到 的路径上。
由第二个性质我们可以得到 。其中 是原树上距离,而 是点分树上 。
有了这个重要的性质,就可以直接暴力跳祖先维护了。
本文作者:TulipeNoire
本文链接:https://www.cnblogs.com/TulipeNoire/p/Divide_and_Counquer_on_Tree.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步