长链剖分

所谓长链剖分,就是给每个节点标记一个深度最深的长儿子。

长链剖分的优势:对于可以 $O(1)$ 从一个儿子继承所有所需信息的 dp,用长链剖分,更新时直接 $O(1)$ 继承长儿子的信息,其余儿子的信息暴力继承即可。

时间复杂度 $O(\sum\limits_{u} \sum\limits_{v \in son_u} len_v)=O(n)$,其中 $len_v$ 为 $v$ 所在长链的长度。

那么,什么 dp 可以 $O(1)$ 从一个儿子继承所有所需信息呢?

能想到的只有:维护的信息仅与深度有关的 dp。

例如,$f[u][j]$ 代表与 $u$ 距离为 $j$ 的节点的数量,$g[u][j]$ 代表与 $u$ 距离为 $j$ 的节点的权值和等等。

怎么 $O(1)$ 继承?

维护一个大小为 $O(n)$ 的数组和一个指针,每次来到长链链头 $u$ 时开出一块长为 $len_u$ 的空间给它,即令 $f_u=pos$。

然后对于长儿子 $son_u$,令 $f_{son(u)}=f_u±1$ 即可 $O(1)$ 继承与深度有关的信息。

对于长链剖分,树上差分很有用哦~

posted @ 2021-11-30 20:50  CharlieVinnie  阅读(35)  评论(0编辑  收藏  举报