长链剖分 学习笔记

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

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

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

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

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

几个应用

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

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

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

我们考虑找到唯一的 \(x\) 满足 \(2^x\leq 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。

posted @ 2021-02-04 17:14  ycx060617  阅读(130)  评论(0编辑  收藏  举报