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

虚树学习笔记

时间:2023-07-27 17:11:45浏览次数:38  
标签:top LCA 笔记 stk 学习 lca 虚树 关键点

观前须知:本博客中 \(k\) 均指关键点数量

-2 前置芝士

你需要会基本的dfs序(下简称dfn)及性质,并且要会写LCA(推荐树剖因为快)

-1 典型特征

关键点 \(\sum k \le1e5\) 之类的很小的数

虚树的特点是只保存关键点及其 LCA

0 引入

例:\(\color{green}CF613D\)

这个树上问题可以说非常符合 \(\sum k\) 小

题面自己看,接下来考虑构建一个所谓的 虚树

1 构造

虚树的构建是一个增量算法,第一步是将 \(k\) 个关键点按dfn排序,按顺序一一加入(可以先加入根从而便于构造)

之后我们建一个栈(称为 \(stk\) ),我们希望这个栈可以保存一条从根出发的 不连续的路径

我们希望任意时刻,插入一个点 \(a[k]\) 后, \(stk[1]=root,stk[top]=a[k],stk[x]\) 是 \(stk[x-1]\) 后代

虚树上连边 \(u\to v\) 都是在 \(v\) 出栈时连边

现在考虑如何在已经建了一部分的虚树后插入一个新点 \(x\)

令 \(l\) 为 \(lca(x,stk[top])\)

  • \(l=stk[top]\) 直接在栈内加入 \(x\) 因为此时 \(x\) 在 \(stk[top]\) 子树内

  • \(l \neq stk[top]\) 寄,他不在咋搞 不写了tnnd

对于情况二,我们可以知道此时 \(x\) 不在栈顶的子树内

立马"回溯",弹栈直到 \(dep_{top-1} < dep_{l}\),此刻 \(lca\) 以下的原先的点都被打飞了,弹出的同时我们每次把 \(stk[top]\) 和 \(stk[top-1]\) 连边

但还有一件事,万一 \(l\) 不在虚树内呢?那就入栈

当所有点插入完全后,我们完全回溯,把栈弹干净同时连边

好耶,虚树建好了

这样为什么对呢?其实看一遍过程会发现显然我们所希望的 LCA 和关键点都在虚树内了,正确性是显然的

代码实现:

void ins(int x){
	if(tp==0){//tp is 栈顶 
		st[++tp]=x;
		return;//如果当前虚树空,无脑入栈 
	}
	int L=lca(x,st[tp]);//如上文,栈顶和插入点lca,此处是原树上的lca 
	while(dep[L]<dep[st[tp-1]]){
		add(st[tp-1],st[tp--]); 
	}
	if(dep[L]<dep[st[tp]]) add(L,st[tp--]);
	if(st[tp]!=L) st[++tp]=L;	
	st[++tp]=x;
	return;
}

复杂度分析:

\(k\) 个关键点入栈一次出栈一次 \(O(k)\),LCA \(O(klogn)\),排序 \(O(klogk)\)

标签:top,LCA,笔记,stk,学习,lca,虚树,关键点
From: https://www.cnblogs.com/exut/p/17584807.html

相关文章

  • Linux学习(3)Redis开机自启动
     1.指定配置启动前台启动redis服务会阻塞整个会话窗口,如果需要通过后台方式启动redis服务,那么必须通过修改redis配置文件的方式来解决。redis配置文件即redis.conf,是存放在redis安装目录下面的。因此,首先需要切换到redis安装目录下:cd/usr/local/src/redis-6.2.6......
  • Cache学习(七)(八)(九)
    Query的概念以及操作方法(有点难,还要再研究一下) 类似于sql query的结构代码:  M语句的Sql常规增删改查以及PLIST增删改查 有返回值的方法执行时需要将d改为w  plist入参 意义:从前端csp传递到后端调用方法与数据库交互   ......
  • 【学习笔记】
    在标签中填写onclick事件调用函数时,不是 onclick=函数名,而是 onclick=函数名+(),代码如下所示:<!DOCTYPEhtml><html><head>  <metacharset="utf-8">  <title>*来自菜鸟教程(runoob.com)</title></head><body>  <h1>我的第......
  • MySQL学习笔记
    一、SQLSQL语句通用语法SQL语句可以单行或多行书写,以分号结尾。SQL语句可以使用空格/缩进来增强语句的可读性。MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。注释:单行注释:--注释内容或#注释内容(MySQL特有)多行注释:/*注释内容*/SQL分类DDL:DataDe......
  • 深入Scikit-learn:掌握Python最强大的机器学习库
    本篇博客详细介绍了Python机器学习库Scikit-learn的使用方法和主要特性。内容涵盖了如何安装和配置Scikit-learn,Scikit-learn的主要特性,如何进行数据预处理,如何使用监督学习和无监督学习算法,以及如何评估模型和进行参数调优。本文旨在帮助读者深入理解Scikit-learn,并有效地应用在......
  • 牌效学习
    面子固定与雀头固定https://tenhou.net/2/?q=789m122356p23678s固定面子能得到更多的进张,但是要承担听单骑的风险。能做出断幺九之类的全体役时,可以固定雀头。当有暗刻时,固定面子可以从暗刻中去掉一张形成雀头。面子可以形成四连形时,就会留下两面单骑。宝牌所在侧也会影响......
  • c++学习
    下面的内容都是在linux环境下。网络I/O有阻塞IO,非阻塞IO,IO多路复用,信号驱动IO和异步IO五种方式。1.阻塞非阻塞阻塞与非阻塞针对的是数据就绪阶段,如果是阻塞,则程序将一直等待,知道数据就绪,然后开始读取,如果是非阻塞,则若数据还未就绪,程序可以先执行别的事务,但是I/O还是要......
  • 数据结构练习笔记——求解由单链表表示的一元多项式的值
    求解由单链表表示的一元多项式的值【问题描述】一个形如\[a_0x^0+a_1x^1+...+a_nx^n\]的一元多项式含有n+1项,每一项由系数和指数唯一确定,可表示成由系数项和指数项构成的一个二元组(系数,指数),一元多项式则可以表示成二元组的集合{(a0,0),(a1,1),(a2,2)...(an,n)},可看成是数据......
  • 尚硅谷Java 宋红康2023版 - 学习笔记
    尚硅谷Java宋红康2023版-学习笔记观看地址https://www.bilibili.com/video/BV1PY411e7J6JDKJREJVMjdk是开发包,jre是运行包,jvm是java虚拟机(最小核心)javajdk版本8或11我这里就用8了。......
  • Dokcer学习之旅(1)——运行一个简单的容器
    基本概念镜像我们都知道,操作系统分为内核和用户空间。对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像(Image),就相当于是一个root文件系统。比如官方镜像ubuntu:18.04就包含了完整的一套Ubuntu18.04最小系统的root文件系统。Do......