树分块学习笔记
本文主要参考 周欣 《浅谈一类树分块的构建算法及其应用》
-
的概念
一个树簇() 是一个树上的连通子图, 有至多两个点和全树外部相接。
这两个点称为界点, 其它的包含在里面的点叫内点。 两个界点之间的路径称为簇路径()。
簇是可以合并的, 具体来说有 和 两种操作,
可以证明经过上面两个操作后整个树会变成一个簇, 合并的过程会形成一棵二叉树, 称为 , 与本文关系不大, 故略去。
-
树分块的基本结构
基本思想 : 把一棵树经过划分划分成若干个簇的并, 把所有的界点与它们的簇路径建成一棵新的树,这棵树称为收缩树。
设每个簇大小为 , 则会划分出 个簇。
可以发现,这与分块的结构很类似, 界点和簇路径可以看成整块, 中间夹着的内点看成散块,于是只要我们能够快速维护出这些信息,就可以很方便的解决许多问题。
-
树分块的构建
算法 : DFS 寻找哪些点需要成为界点,再根据界点找到簇路径即可,用一个栈维护当前未归类的边。
只有在下面 3 种情况发生时,把当前点设为界点 :
- 当前点为根,我们强制规定根必须是界点.
- 当前点有两个或以上含有界点的子树 .
- 栈中的边数大于等于 .
容易证明这三种情况的总发生次数不会超过 次。
问题抽象为给定一个数 及两个序列 (表示各个子树中未归类的数量),(各个子树中是否存在界点)
我们要做的是,将序列切割成若干子段,使得每一段中 的和不大于 ,且 的和最多为 。
可以直接贪心,每次截取最长的合法前缀,证明略。 这样的块的总数是不超过 的。
本文作者:henrici3106
本文链接:https://www.cnblogs.com/henrici3106/p/15760944.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步