【学习笔记】树分治

点分治

普通的分治在一段子段 [l,r] 中处理和 mid 有关的信息然后递归处理 [l,mid)(mid,r]。由于中点的优秀性质这种看似暴力的做法实际复杂度是 O(nlogn) 的。

点分治是一种把分治思想运用到树上解决问题的算法(但是其实更多人愿意称其为数据结构?)。它一般适用于与路径有关的问题。

考虑我们现在处理的是子树 p,仅仅根据子节点很显然会导致分治复杂度出错。我们希望寻找一种递归方式使得递归层数尽量地小。联想到以树的重心为根每个子树大小不超过其一半的性质,每次找到一个连通块的重心,处理经过这个重心的答案,然后把这个重心删去递归其子树。

注意我们处理的是这个重心的答案,于是我们要减去来自同一子树的贡献。具体的做法有很多种。你可以把 加贡献和处理答案分开做,对于一个子树先把它的答案统计完再加入其贡献。这种写法常数略大。

你也可以 记录一个点属于哪个子树然后离线下来做,在本身就需要离线处理贡献的题目里面很好用。

如果记录一个节点属于哪个子树但是不好维护其在那个子树中的贡献也可以把答案统计完后 用类似容斥的做法 把来自同一个子树的贡献减去。

点分树

尝试把每层找到的重心和上一层的重心连边形成一棵点分树。

有一些优秀的性质。

首先树高是 logn 的。因为点分治只会进行 logn 层。这使得暴力跳树有了正确性。

然后所有节点的子树大小和是 O(nlogn) 级的,因为每个重心会访问其子树大小个点,所以复杂度延续点分治的分析。

然后点分树上 x,y 两点的 lca 一定是原树上 x,y 路径上的一个点。其他的点可能都没有关系。

所以如果我们的答案只要知道路径上任意一个点而不是硬性要求 lca,就可以暴力跳点分树求解。单论点分树复杂度一次是 O(logn) 的。

posted @   Wind_Leaves_ShaDow  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示