【学习笔记】虚树

简介

虚树就是一种很无奈时的无赖做法
--唐末
当题目中答案只与某些关键点有关,而关键点很稀疏时,就可以用虚树将整棵树浓缩。

建虚树

  • 方法一:
    二次排序 + LCA 连边
  1. 将所有关键点按 dfn 序排序,求出相邻两个点的 LCA(确定虚树中的所有点)。
  2. 将所有 LCA 及关键点去重并再次按 dfn 序排序。
  3. 算出相邻两个点 x,y 的 LCA 并与 y 连边。
    证明:若 x 为 y 的祖先,即 y 是 x 的第一个儿子,由于 dfn 序相邻,所以两者之间无其它点,所以只会被他们相连。
    若 x 不为祖先,即 y 不是 LCA 的第一个儿子,由于 dfn 序相邻,所以 y 到 LCA 之间无其他点。
    性质:可以发现,每两个关键点最多会生成一个虚点,所以算上钦定的根节点 1,虚树上最多会有关键点数 \(\times 2\) 个节点(类似满二叉树)。
  • 方法二
    单调栈
    首先单调栈维护的是虚树中的一条链。
  1. 将 1 节点压入栈,并将所有关键点按 dfn 序排序。
  2. 将排好序的点逐个加入栈:
    求出当前点 x 与栈顶结点 y 的 LCA 节点 l,
    若 y 就是 l,说明 x 与 y 在一条链上,直接把两个点连起来就行;
    若 l 不是栈顶结点,说明不在同一条链上,就将多余的点弹掉(并同时连边),并判断 l 是否在栈内,若不在就压入栈(具体步骤看 OIwiki)。
  3. 将还在栈内的点弹掉并连边。
posted @ 2025-05-26 19:54  GuoSN0410  阅读(16)  评论(0)    收藏  举报