虚树学习笔记
有些题目会查询一些树上的点,这些点的总数是确定的,我们希望单次查询与给出点的数量有关,这样整个算法的总时间复杂度就有保证了。但查询的信息可能与这些点形成的结构有关,所以我们不得不在原树上进行……吗?
我们可以依托于这些给出的点,建出一些仅依托于这些点的小树,而且这颗小树的节点个数与给出点的总数是同级的,于是我们便可以通过这颗小树的结构关系得出答案,我们称这颗小树为虚树。
建立虚树的两种方法:
1.二次排序
- 先把给出的点按 \(dfs\) 序排序,把相邻两个点的
lca加入进点集。 - 去重,再排序一边,把 \(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\) 的边。
然后虚树就建完了,不难发现和二次排序本质相同。

浙公网安备 33010602011771号