首页 > 其他分享 >【学习笔记】虚树

【学习笔记】虚树

时间:2023-09-11 21:45:07浏览次数:35  
标签:int 笔记 学习 数组 LCA 排序 虚树 关键点

点击查看目录

目录

虚树,不是虚数 \(i\)。

定义

在树形 dp 等题目中,树中点很少,可以直接跑 dp。

但是如果很大但是我们只需要查询很少的一些点呢?

我们称某次询问的点为 【关键点】

虚树

我们看上图,只有左边子树的两个节点被查询了,那右边的子树有 dp 的必要吗?

因此我们把一棵大树缩成一棵较小的树。

这就是【虚树】的概念

构造虚树

先来看看虚树的形态。

我们选择了查询结点,但是结点之间的 LCA 也是储存着信息的,需要加入。

以上道题来说,其虚树形态较为简单:

上一个比较大的虚树:

但是我们不可能 \(O(n^2)\) 两两查询 LCA,于是就很容易想到求一下 dfs 序,对于关键点放入一个容器排序,之后对于容器内相邻的关键点查询 LCA,加入虚树。

而如何构造虚树就成了难题。

无论虚树是什么样子,只要祖先与子孙的关系没有变,点就可以加入虚树。

所以为了方便,将 \(1\) 号节点首先加入虚树。

二次排序+LCA 连边

多个节点的 LCA 可能是同一个,不能多次加入。

因此我们将得到的需要加入的 LCA 和关键点第二次排序,然后去重即可。

然后,枚举这个数组的相邻两点 \(x\) 和 \(y\),求得其 LCA 并连接 LCA 和 y。

证明其正确性:

  • 首先明确:因为排序使得 \(x\) 和 \(y\) 的 dfs 序是相邻的,所以 \(x\to y\) 路径上没有关键点。

  • 若 \(x\) 是 \(y\) 的祖先,那么直接让 \(x\) 连到 \(y\) 上。

  • 若 \(x\) 不是 \(y\) 的祖先,则将 LCA 作为 \(y\) 的祖先连边即可。

  • 而第一个点是我们加入的树根 \(1\),所以不存在第一个点未与一个节点连接的可能。

总结,具体实现为以下步骤:

  1. 将关键点按照 dfs 序排序。

  2. 将数组中相邻的关键点的 LCA 加入数组。

  3. 将数组二次排序。

  4. 对数组进行去重。

  5. 对数组相邻的点寻找 LCA,连边。

Miku's Code
#define il inline
#define rg register int 
int dfn[maxn];
bool vis[maxn];
int h[maxn],m,a[maxn],len;

bool comp(int x,int y) <% return dfn[x]<dfn[y]; %>

il void build_virtual_tree(){
  	sort(h+1,h+m+1,cmp);
  	for(rg i=1;i<m;++i){
   		a[++len]=h[i];
    	a[++len]=LCA(h[i],h[i + 1]);
 	 }
 	 a[++len]=h[m];
  	sort(a+1,a+len+1,comp);
  	len=unique(a+1,a+len+1)-(a+1);
  	for(rg i=1;i<len;++i){
    	int lca=LCA(a[i],a[i+1]);
    	add_edge2(lca,a[i+1]);
  	}
}

单调栈

米浴和你说说这个道理。

米浴说的道理—————

标签:int,笔记,学习,数组,LCA,排序,虚树,关键点
From: https://www.cnblogs.com/sonnety-v0cali0d-kksk/p/Virtul_Tree-written_by_sonnety.html

相关文章

  • 笔记工具的要求
    #笔记工具##前言生活总会碰到一些事情,然后获得一些经验,可是过段时间又忘了。工作也是一样,碰到了,总结了,又丢了。因此需要把这些经验、总结,记录下来,时不时回顾,保持较好状态。最早是用evernote,然后迁移到为知。用过为知笔记几年,还冲了会员,关闭。数据放在外部不安全、不稳定。虽然提......
  • 一文了解机器学习中分类和回归的差异
    本文所有内容整理自网络。完整内容可以点击这里获取:完整资料下载地址前言分类和回归是数据挖掘和机器学习中常见的两个预测问题。分类算法分类算法是拟合一个模型或函数的过程,该模型或函数有助于将数据分为多个类别,即离散值。在分类中,根据输入中给定的一些参数,数据被分类到不同的标......
  • MySQL学习01
    一、数据库简介1、为什么需要数据库1、磁盘->高级缓存->寄存器->CPU数据存储在内存中,但是内存大小有限、不可能存储所有数据,并且掉电后数据丢失2、为了让程序在关机重启后数据依然可以使用,必须把数据保存在磁盘文件中3、随着程序功能越来越复杂、数据量越来越多、数据关系也......
  • stun 学习记录
    NAT网络拓扑NAT是将内网地址映射转换为外网地址的一种地址转换方式,这节省了有限的IP地址资源。一般来讲,分为对称型NAT和圆锥形NAT,其中圆锥形NAT又分为完全圆锥型NAT、IP限制圆锥型NAT、Port限制圆锥型NAT。1.完全圆锥型NAT完全圆锥型NAT是指同一个内网IP1+Port1向任何外网发送数据,......
  • 《Java编程思想第四版》学习笔记27
    //:DirList2.java//UsesJava1.1anonymousinnerclassesimportjava.io.*;publicclassDirList2{publicstaticFilenameFilterfilter(finalStringafn){//Creationofanonymousinnerclass:returnnewFilenameFilter(){St......
  • MYSQL笔记
    一、创建列表1、 创建库CREATEDATABASEwjd_table2、 删库,dropdatabasetable_name;3、 选库usetable_name;4、 类型分别有:1) char或character(负责数据,需设定长度);2) int或inteser(数字为整数或负数);dec(提供数值空间);3) datatime或timestamp(负责记录时间和日期);4) blob(大量文......
  • Ansible学习笔记03:主机组
    主机组在Ansible中,主机组(HostGroup)是一个概念,用于将具有相似特性或需求的多个主机归为一组,以便进行集中管理和操作。例如,你可能希望将所有的Web服务器归为一个主机组,以便可以统一应用配置和管理。在Ansible中,可以通过在Inventory文件中指定主机组,来方便地管理和组织主机。Inventor......
  • openGauss学习笔记-66 openGauss 数据库管理-创建和管理schema
    openGauss学习笔记-66openGauss数据库管理-创建和管理schema66.1背景信息schema又称作模式。通过管理schema,允许多个用户使用同一数据库而不相互干扰,可以将数据库对象组织成易于管理的逻辑组,同时便于将第三方应用添加到相应的schema下而不引起冲突。管理schema包括:创建schema......
  • python pandas学习
    importpandasaspdm_list=[('join',25,'male'),('1isa',30,'female'),('david','18','male')]df=pd.DataFrame(m_list,columns=['Name','age','gend......
  • C笔记--c++编译过程
    c++编译过程 参考资料:尚硅谷bilibili视频2023版......