虚树学习笔记

虚树

将树上某些关键点拿出来,保持一定祖先关系形成的树

性质

  1. k 个关键点构成的虚树大小上线为 2k1,在 虚树形态为一颗完全二叉树时实现
  2. 虚树上节点集合为按 dfs 序排序后相邻节点的 lca 所构成的集合与关键点集合的并集

构建

不妨设 dfs 序先左后右

考虑按 dfs 序排序后增量构建与虚树的最右链

最右链:当前加入的最后一个点到虚树根的一条链(当前虚树最右端的链)

具体实现用栈来

当加入一个新点时,与最右链上的点进行比对,加入虚树

讨论加入新点 x 的情况,设 y=lca(x,sttop)

  1. xsttop 的子树里

    在最右链中加入 x 即可

  2. x 不在 sttop 的子树里且在 sttop1 的子树里且 y 不为 sttop1

    此时 ysttopsttop1 的路径上

    更新最右链(sttop1sttop 变为 sttop1yx ),并将 sttop1sttop 加入虚树边集

  3. x 不在 sttop 的子树里且在 sttop1 的子树里且 ysttop1

    更新最右链(sttop1sttop 变为 sttop1x),并将 sttop1sttop 加入虚树边集

  4. x 不在 sttop1 的路径里

    根据 y 所在位置退栈更新最右链直至变为Case 1/2/3

代码实现

int tp=0,len=0;
int st[maxn],b[maxn];
void ins(int x){
	if(tp==0){st[++tp]=x;b[++len]=x;return ;}
	int p=lca(st[tp],x);
	while(dep[st[tp-1]]>dep[p])add(st[tp-1],st[tp]),tp--;
	if(st[tp]!=p){
		if(st[tp-1]==p){add(st[tp-1],st[tp],0);tp--;}
		else{add(p,st[tp]);b[++len]=p;st[tp]=p;}
	}
	st[++tp]=x;b[++len]=x;
	return ;
}
posted @   juju527  阅读(55)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示