前言
简单说两句
正文
大概作用
就是将一个树形转化为线形,可以使用线段树、树状数组等各种数据结构加以维护。
基本概念
- 重结点:子树结点数目最多的结点
- 轻节点:父亲节点中除了重结点以外的结点
- 重边:父亲结点和重结点连成的边
- 轻边:父亲节点和轻节点连成的边
- 重链:由多条重边连接而成的路径
- 轻链:由多条轻边连接而成的路径
性质
- 如果(u, v)是一条轻边,那么size(v) <(=) size(u)/2
- 从根结点到任意结点的路所经过的轻重链的个数必定都小与O(logn)
代码
(个人码风有点不好,请见谅)
需要两次DFS
第一次DFS
1 | int fa[maxn],son[maxn],siz[maxn],dep[maxn]; |
第二次DFS
这是树剖的关键,也是树形转线形的重要部分(如果讲的不好请见谅)
这一步是将整个树分成若干条重链。每个节点标记一个dfs序,将树上的点变成一个序列中的编号,同样记录下这个编号对应的节点,我们还需要记录每一条重链的开端节点(具体为什么可以看看我那例题的文章)。
为什么这样,由于蒟蒻也讲不太清楚,所以就偷懒不说了,望见谅。
(就这样水了过来)
给出代码:
1 | int top[maxn],in[maxn],id[maxn],tot; |
结束了。。。
(还有一些奇奇怪怪的复杂度证明等等请大家baidu才不说我不会呢!)
例题
下面如果还记得的话会更新一点例题:
- 月下“毛景树”
待更新······