Kruskal 重构树
感谢 Alex_Wei 的博客,让我受益匪浅。
回忆 Kruskal 算法的过程,按边权从小到大排序,若当前边 $u,v$ 在当前图上还不连通,则加入该边,并查集维护这个过程。
Kruskal 重构树就是在加入 $(u,v)$ 时,建立虚点 $x$,令点权 $w_x=w(u,v)$,建边 $x\to id_u$ 和 $x\to id_v$,并将 $id_u,id_v$ 设为 $x$。这样得到一棵 $2n-1$ 个点的二叉树,初始的节点都是树上的叶子,且满足大根堆的性质。
一个应用是求出 $u$ 只经过边权 $\le x$ 的边最多可以到达多少个节点。因为 $w_{fa_u}\ge w_u$,可在重构树上倍增,找到 $u$ 深度最浅的祖先 $f$ 满足 $w_f\le x$,答案为 $f$ 的子树内的叶子个数。
当问题变为点权的限制后,也可以用重构树解决。一种解决方法是将 $w(u,v)$ 设为 $\max(w_u,w_v)$,然后用边权的方法做。
存在另一种不需要建虚点的建树方法。按点权从小到大排序,设当前考虑到点 $i$,遍历每条边 $(i,u)$,若 $u$ 已被考虑过即 $w_u\le w_i$,且 $i,u$ 不连通,则建边 $i\to id_u$。这样构造显然也满足大根堆的性质,但是它是一棵多叉树。
例题
求出满足一类限制,满足二类限制,满足一类和二类限制的答案 $A,B,C$,答案即为 $A+B-2C$。
考虑加入父亲为 $x$ 的点 $i$ 对 $A,B,C$ 的影响。$B$ 增量显然是 $i-1$,$A$ 和 $C$ 的增量相同,设 $c_i$ 表示有多少条路径 $u\to i$ 满足 $u$ 是路径上的最小值,$A$ 增量就是 $c_i$。考虑 $c_i$ 如何转移,因为若路径 $u\to x$ 满足 $u$ 是路径最小值,则 $u\to i$ 一定也满足,再加上路径 $x\to i$,即 $c_i=c_x+1$。综上,每次增量为 $i-1-c_i$。
于是只需处理初始的 $A,B,C$ 和 $c_i$ 即可。建出小根堆和大根堆的点权多叉重构树 $T_{\min}$ 和 $T_{\max}$。点 $i$ 对 $A,B$ 的贡献是 $i$ 分别在 $T_{\min}$ 和 $T_{\max}$ 的 $siz_i-1$,因为子树内的点都是可以满足 $\le i$ 或 $\ge i$ 的限制到达的。$c_i$ 就是 $i$ 在 $T_{\min}$ 上的深度。$C$ 也就是统计有多少 $x,y$ 满足 $x$ 在 $T_{\min}$ 上是 $y$ 的祖先,$y$ 在 $T_{\max}$ 上是 $x$ 的祖先,这个树状数组随便计算就好了。复杂度 $O(n\log n)$。
这个就是上述的经典应用。建出 Kruskal 重构树,找到第一个 $f$ 满足 $w_f>S$,在 $f$ 的子树内找 $dis_i$ 最小值即可。

浙公网安备 33010602011771号