虚树学习笔记

有些题目会查询一些树上的点,这些点的总数是确定的,我们希望单次查询与给出点的数量有关,这样整个算法的总时间复杂度就有保证了。但查询的信息可能与这些点形成的结构有关,所以我们不得不在原树上进行……吗?

我们可以依托于这些给出的点,建出一些仅依托于这些点的小树,而且这颗小树的节点个数与给出点的总数是同级的,于是我们便可以通过这颗小树的结构关系得出答案,我们称这颗小树为虚树。

建立虚树的两种方法:

1.二次排序

  1. 先把给出的点按 \(dfs\) 序排序,把相邻两个点的lca加入进点集。
  2. 去重,再排序一边,把 \(lca_{x_{i-1},x_i}\)\(x_i\) 连边。

由于已经按dfs序排序了,所以 \(lca_{x_{i-1},x_i}\) 一定是 \(x_i\) 深度最浅的祖先。

2.dfs序单调栈

依旧先按dfs序排序,把节点 \(u\) 入栈的时候。

判断栈顶是否是 \(u\) 的祖先,如果不是那么记录栈顶和 \(u\)lca,弹出栈顶。

如果当前栈顶不是这个lca,连栈顶和lca的边,将lca入栈。

加入当前点,连连栈顶和 \(u\) 的边。

然后虚树就建完了,不难发现和二次排序本质相同。

posted @ 2026-01-16 15:45  Sgt_Dante  阅读(3)  评论(0)    收藏  举报