树上静态链分治
(指针)数组平移:
f[x] = f[son[x]] + 1
DSU on tree
名字大概来源于并查集中的按秩合并。但是实际上应该从重链剖分角度去分析。用来离线得到每个节点子树的信息(如维护子树权值的平衡树)。要求:
- 各个节点对当前子树根的贡献独立。
- 可以在小于 \(O(siz)\) 的时间内直接引用某一个儿子的计算结果。
- 每个节点的有值的状态总数规模不超过 \(siz\)。
也就是直接 \(O(1)\) 引用重儿子的数据,再进行 \(siz_x-siz_{son_x}\) 次 \(O(k)\) 的暴力插入,则最后复杂度即为 \(O(nk\log n)\)。
关于证明,考虑每个点的信息仅在其自身和到祖先的每条重链链顶被暴力 \(O(k)\) 插入,而到祖先的重链总共 \(O(\log n)\) 条。
长链剖分
没有 DSU 的泛用性,但更加适用于 维护的信息仅与深度相关 的情形。也就是可以从长儿子快速转移。这时候可以做到 \(O(nk)\)。
线段树合并
- 合并过程中需要子树内状态的前后缀和等 \(j\) 值域 上的信息。
- 可以在其中一个节点为空时直接 \(O(1)\) 合并。
- 每个节点的有可能不同值的状态总数规模不超过 \(siz\)。
这种思路可能可以称为 整体DP。
关于以上的 3 中的“可能不同”,考虑以下问题:
- DP 时需要支持整体对 \(x\) 取 \(\min\),两两相加,维护区间 \(\min\)。
我们发现前者可以打懒惰标记,但是这样就意味着空白节点不一定值为 \(0\)。
又要进行相加,传参数很麻烦,我们可以考虑:
-
对于存在儿子的节点,直接暴力新建另一儿子再下传标记。这样新建出来的儿子一定整个区间值都相等。
-
对于合并的节点存在一整个区间值相等的情形,一定不存在儿子,直接整体合并到另一个上。
容易发现这样,值域上每个位置,本质不同权值的数目仍然很少,因此复杂度仍然正确。感性理解,就是每次插入形成的 \(\log\) 个节点每个再额外挂一个儿子,因此常数略大。
CF1824C

浙公网安备 33010602011771号