长链剖分 学习笔记

这玩意鸽了好多((>5))天,主要是因为那个 OmNom jxd 作业太难了。

长链剖分跟重链剖分统称树链剖分,所以它们很相似。

重剖是按照子树大小 (sz) 来找重儿子 (wson),而长剖是按照子树最大深度 (mxdep) 来找深儿子 (dson)。每个点在且仅在一条长链里。

一个小性质:类比跳重链是对数复杂度的,跳长链是根号的。证明显然。但是不知道有什么用?

长链与叶子显然形成双射(so does 重链)。

几个应用

应用啥的还是跟重剖很本质不同的。

(mathrm O(1))(k) 级祖先

(omega(1)) 的很多,倍增或者跳重链都是对数的。长剖可以做到 (mathrm O(nlog n)-mathrm O(1))

我们考虑找到唯一的 (x) 满足 (2^xleq k<2^{x+1}),这个预处理个 (log) 数组即可做到。我们预处理出倍增跳祖先的数组,那么直接就可以跳到 (2^x) 级祖先。接下来需要再往上跳 (k-2^x)。由于 (k<2^{x+1}),所以 (k-2^x<2^x)。而既然当前处于的节点是某节点往上跳 (2^x) 步得到的,那么它所在长链长度一定 (geq 2^x)。我们考虑预处理时,对每条长链,求出其中每个点关于链顶对称的节点。由于每个点在且仅在一条长链中,所以这一步是线性的。那么再往上跳 (k-2^x) 就直接做了(就调用当前节点所在长链的相关数组,可能在链顶之上也可能在之下)。

模板题 code(感谢 xht)

类似 dsu on tree 的东西

这大概算是长剖最最常用的应用了吧。

zszz,dsu on tree 需要满足子树 (x) 的信息量为 (mathrm O(sz_x))。那更强地,如果满足为 (mathrm O(mxdep_x-dep_x)) 呢?那可以把 dsu on tree 中继承重儿子改成继承深儿子,复杂度是线性的。

证明:显然所有浅儿子 (x) 对复杂度贡献 (mathrm O(mxdep_x-dep_x))。而浅儿子和长链形成双射,所以可以看成每条长链(链顶为 (x))对复杂度贡献 (mathrm O(mxdep_x-dep_x)),而这恰好是长链长度!根据每个点在且仅在一条长链中,复杂度得证。

这玩意可以优化某些关于深度的统计,还可以优化 DP 哦(可以看成较复杂的关于深度的统计)。

优化贪心

这大概算是长剖最最不常用的应用了吧。

见例题 bzoj3252 和 cf526G。

珍爱生命,远离抄袭!
原文地址:https://www.cnblogs.com/ycx-akioi/p/clpfo.html