树上静态链分治

(指针)数组平移:f[x] = f[son[x]] + 1

DSU on tree

名字大概来源于并查集中的按秩合并。但是实际上应该从重链剖分角度去分析。用来离线得到每个节点子树的信息(如维护子树权值的平衡树)。要求:

  1. 各个节点对当前子树根的贡献独立。
  2. 可以在小于 \(O(siz)\) 的时间内直接引用某一个儿子的计算结果。
  3. 每个节点的有值的状态总数规模不超过 \(siz\)

也就是直接 \(O(1)\) 引用重儿子的数据,再进行 \(siz_x-siz_{son_x}\)\(O(k)\) 的暴力插入,则最后复杂度即为 \(O(nk\log n)\)

关于证明,考虑每个点的信息仅在其自身和到祖先的每条重链链顶被暴力 \(O(k)\) 插入,而到祖先的重链总共 \(O(\log n)\) 条。

长链剖分

没有 DSU 的泛用性,但更加适用于 维护的信息仅与深度相关 的情形。也就是可以从长儿子快速转移。这时候可以做到 \(O(nk)\)

线段树合并

  1. 合并过程中需要子树内状态的前后缀和等 \(j\) 值域 上的信息。
  2. 可以在其中一个节点为空时直接 \(O(1)\) 合并。
  3. 每个节点的有可能不同值的状态总数规模不超过 \(siz\)

这种思路可能可以称为 整体DP


关于以上的 3 中的“可能不同”,考虑以下问题:

  • DP 时需要支持整体对 \(x\)\(\min\),两两相加,维护区间 \(\min\)

我们发现前者可以打懒惰标记,但是这样就意味着空白节点不一定值为 \(0\)

又要进行相加,传参数很麻烦,我们可以考虑:

  1. 对于存在儿子的节点,直接暴力新建另一儿子再下传标记。这样新建出来的儿子一定整个区间值都相等。

  2. 对于合并的节点存在一整个区间值相等的情形,一定不存在儿子,直接整体合并到另一个上。

容易发现这样,值域上每个位置,本质不同权值的数目仍然很少,因此复杂度仍然正确。感性理解,就是每次插入形成的 \(\log\) 个节点每个再额外挂一个儿子,因此常数略大。

CF1824C

posted @ 2023-05-09 19:30  音街ウナ  阅读(24)  评论(0)    收藏  举报