维护连通块

现有一棵 nn 个节点的树。我们构建一最小的连通块 S(l,r)S(l,r),包含编号在 [l,r][l,r] 中的所有节点。多次询问,每次对于任意一对 [l,r][l,r],询问关于这连通块的信息。

如果可以离线/可持久化,此类问题有一通用思路:用扫描线维护“rr 固定时不同 ll 构成连通块的信息”。若 [p,q][l,r][p,q]\subseteq[l,r],则 S(l,r)S(p,q)S(l,r)\supseteq S(p,q);对于一固定的 rr,我们维护 ll 分别取 r,r1,,1r,r-1,\cdots,1(向左拓展)时,连通块的增量。对于点 xx,我们记录 tr(x)t_r(x) 表示 rr 固定时使得 xS(l,r)x\in S(l,r) 的最大的 ll。假设已经对于 rr 维护好了;现在拓展到 r=r+1r’=r+1

x{r,r+1}x\notin \{r,r+1\},则 tr+1(x)tr(x)t_{r+1}(x)\neq t_{r}(x)

  • xxrrr+1r+1 的简单路径上,且
  • tr+1(x)=rt_{r+1}(x)=r

的充分必要条件。

考虑任意 ll。由于 SS 是极小的,故将 r+1r+1“加入”S(l,r)S(l,r) 得到 S(l,r+1)S(l,r+1)需找到 r+1r+1 和连通块在树上最接近节点之间的路径,将路径上所有点加入连通块;由树的性质,此路径是通向 [l,r][l,r] 中任意节点的必经之路,也即 r,r+1r,r+1 的最短路径的某一前缀。又当 l=rl=r 时,S(l,r+1)S(l,r+1) 就是该路径本身;再有 [p,q][l,r]S(l,r)S(p,q)[p,q]\subseteq[l,r]\Longrightarrow S(l,r)\supseteq S(p,q),故本命题得证。

因此,我们需将整条路径上的点的最大出现时间整体覆盖tr+1(x)=rt_{r+1}(x)=rr+1r+1 本身除外,它是 tr+1(r+1)=r+1t_{r+1}(r+1)=r+1)。可以使用珂朵莉树和树剖维护连续的 t(x)t(x) 相同的一段。设 ΦΦ 表示连续段个数。每次覆盖操作会对 O(logn)\newcommand\bigO{\operatorname{O}}\bigO(\log n) 条重链执行“删除若干连续段,加入 O(1)\bigO(1) 个连续段”的操作。又 ΦnΦ\leq n,则 ΦΦ 的总变化量是 O(nlogn)\bigO(n\log n) 的。因此若用对数级别有序关联式容器(如 std::map),总时间复杂度为 O(nlog2n)\bigO(n\log^2 n)(更多…)

More
  • 2023年11月30日

(2022.11.21 重写)

定义

siz(x)\newcommand\siz{\operatorname{siz}}\newcommand\hson{\operatorname{hson}}\siz(x) 表示 xx 的子树大小(含 xx),hson(x)\hson(x) 表示 xx重儿子。将边 (x,hson(x))(x,\hson(x)) 称为一条重边,其余不满足该条件的边称为轻边;将相邻的重边两两相连形成的链称为重链。

命题

一棵以 rt\newcommand\rt{\text{rt}}\rt 为根的树,其重心 cc 满足以下条件:

  • cc 在以 rt\rt 为顶的重链上;(1)(1)
  • cc 的所有祖先(记其中一个为 xx),均满足 siz(hson(x))>siz(rt)2\siz(\hson(x))>\frac{\siz(rt)}{2}(2)(2)
  • siz(hson(c))siz(rt)2\siz(\hson(c))\leq \frac{\siz(rt)}{2}(3)(3)

(更多…)

More
  • 2021年7月23日