树剖学习笔记(二)—— 原理 + 复杂度证明

接上文 树剖学习笔记(一)

tid[x] 里存的是访问到 x 这个节点的时间,之后我们根据这个 tid[] 值建树,所以这个 tid[x] 就是 x 在线段树中的编号。
而 Rank[tid[x]] 就是 x 在线段树中的编号,对应在原树中的编号。

wyj 在时隔十天以后发现自己并没有理解树剖,只是会打板子了而已,于是 wyj 惨兮兮的来这里总结一下
(其实主要是因为被 小 ly D 的很惨 wyj 很不开心嘤嘤嘤TAT


原理

树链剖分原理 —— By ACdreamers

树链剖分目的:树路径信息维护。将一颗树划分成若干条链,用数据结构去维护每条链,复杂度 O(logn)

划轻重链目的:为了让 tid 连续。
我们在用线段树维护链的时候,如果节点编号不连续,那么就无法用线段树。

第二次 dfs 就是连接重边形成重链,具体过程就是:以根节点为起点,沿着重边向下拓展,拉成重链。不在当前重链上的节点,都以该节点为起点向下重新拉一条重链。

也就是说如果 u -> v 是轻边,则 v 成为重链链头,在接下来“将所有重链首尾相连”的步骤时,和其他重链相连。即重链之间由一条不在重链上的边(轻边)连接。

剖分完毕后,每条重链相当于一段区间,然后用数据结构去维护,把所有重链首尾相接,放到数据结构上,然后维护整体。


复杂度

树链剖分执行一次修改/查询的时间复杂度是 O(logn · logn)。

证明
可以发现树链剖分的结构是 沿着链向上跳 + 线段树修改/查询
线段树修改查询操作的时间复杂度是 O(logn);而在树链上每走一条轻边,子树大小就 /= 2,所以最多走 log n 条轻边,复杂度 O(logn)。

你可能感兴趣的:(学习笔记)