虚树初步学习笔记

虚树

给定一棵树,树上有一些关键点,你要建另一棵树,保留关键点,以及任意一对关键点的 \(\text{LCA}\)

当你发现对于一棵树,你只有一些关键点有用的时候,就可以尝试建虚树。

两次排序

思路

先把所有点按 \(\text{dfn}\) 序排序,然后把 \(\text{dfn}\) 相邻的两个点取出来,再把它们的 \(\text{LCA}\) 放进去。

再把所有点按 \(\text{dfn}\) 序排序,然后把 \(\text{dfn}\) 相邻的两个点取出来,设为 \(a_{i-1}\)\(a_i\),那么再把它们的 \(\text{LCA}\) 放进去,同时 \(a_i\) 的父亲就是它们的 \(\text{LCA}\),连边即可。

核心代码

点击开 D
struct note {
	int p; note(int p_=0) { p=p_; return ; }
	friend bool operator < (const note a,const note b) {
		return dfn[a.p]==dfn[b.p]?a.p<b.p:dfn[a.p]<dfn[b.p];
	}
}; set<note> S={},nS={};
y=0,nS=S;
for(auto x:S) { if(y) {
	z=lca(x.p,y),nS.insert(note(z));
} y=x.p; } S=nS;
y=0; for(auto x:S) { if(y) {
	z=lca(x.p,y);
	if(z!=x.p) G[z].insert(mkp(x.p,deep[x.p]-deep[z]));
	nS.insert(note(z));
} y=x.p; } S=nS;

时间复杂度

假设有 \(k\) 个关键点,虚树一共 \(O(2k)\) 个点,时间复杂度是 \(O(k\log k)\)

posted @ 2024-06-23 22:36  fydj  阅读(10)  评论(0编辑  收藏  举报