Splay/LCT 学习笔记
唔,其实我不会 Splay,但是我会 LCT。
众所周知,会 LCT 和会 Splay 是两回事,因为 LCT 只需要旋至根即可。
到现在还是不会,但是先把 LCT 的 Splay 写一下吧。
自己复习用的。
先给代码。
LCT code
int isroot(int x) {return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
int idt(int x) {return ch[fa[x]][1]==x;}
void swp(int x) {
if(!x) return ;
rev[x]^=1;
swap(ls,rs);
}
void pushdown(int x) {
if(rev[x]) {
rev[x]=0;
swp(ls);
swp(rs);
}
}
void pushup(int x) {
if(!x) return;
if(x<=n) ma[x]=-INF;
else ma[x]=val[x];
if(ls) cmax(ma[x],ma[ls]);
if(rs) cmax(ma[x],ma[rs]);
}
void pushall(int x) {
if(!isroot(x)) pushall(fa[x]);
pushdown(x);
}
void add(int y,int x,int i) {ch[fa[x]=y][i]=x;}
void rotate(int x) {
int y=fa[x],i=idt(x);
if(isroot(y)) fa[x]=fa[y];
else add(fa[y],x,idt(y));
add(y,ch[x][!i],i);
add(x,y,!i);
pushup(y);
}
void splay(int x) {
pushall(x);
for(int y;y=fa[x],!isroot(x);rotate(x)) {
if(!isroot(y)) rotate(idt(x)==idt(y)?y:x);
}
pushup(x);
}
void access(int x) {
for(int p=0;x;p=x,x=fa[x]) {
splay(x);
ch[x][1]=p;
pushup(x);
}
}
void makeroot(int x) {
access(x);
splay(x);
swp(x);
}
void split(int u,int v) {
makeroot(u);
access(v);
splay(u);
}
void cut(int u,int v) {
split(u,v);
ch[u][1]=fa[v]=0;
pushup(u);
}
int findroot(int x) {
access(x);
splay(x);
while(pushdown(x), ls) x = ls;
splay(x);
}
主要就是下面这三个函数。分开讨论。
\(rotate\) 操作说明
因为 y = fa[x],那么有 x = ch[y][i]。
旋转的过程即是先用 \(x\) 替换 \(y\),即从 fa[y] 的视角而言。
然后用 \(x, y\) 两点间“包夹”的子树替换 \(x\),即从 \(y\) 的包夹子树的视角而言。
最后将子树的位置用 \(y\) 替换,即从 \(x\) 的视角而言。
\(splay\) 操作
这个主要是旋转方向的问题。
就是第一次有可能对父亲也有可能对自己,若自己与父亲呈一条线idt(y) == idt(x)则转父亲,此时是一个相对于 x <- fa[x] -> fa[fa[x]] 的较平衡形态 \(1\),否则转自己,此时是 fa[fa[x]]->x->fa[x] 的直线形态 \(2\)。
发现无论怎样都需要将 x 再次旋至根,若原来为 \(1\) 形态,旋转后会变成 x -> fa[x] - > fa[fa[x]] 的形态,若原来为 \(2\) 形态,则旋转后会变为 fa[fa[x]] <- x -> fa[x] 的较平衡形态。
对了,还有当前只有一层深度,此时只用旋转 x 即可。
那么这样的话无论怎样都会出现一次较平衡形态,所以可以保证复杂度。
当然,这样只是便于记忆罢了。
严谨的分析其实可以用势能分析法,OI-Wiki 上有,等我学成归来……
然后我们再分析只有单旋的,若开始前是直线状态,则单旋两次后不会出现较平衡形态,而是先出现一个折线,再出现一条直线。
若开始前为折线,则单旋两次后先出现一条直线,再出现一个较平衡状态。
是的,所以若开始前为直线则不能保证复杂度。
同样,这也不是严谨分析……
\(access\) 操作
将 \(x\) 与 原树上的根 之间的路径取出。
注意点:
操作完后 \(x\) 有实儿子,但是只会有左儿子,即原树的到根的链上的节点,所以得到的是一条从 根 到 \(x\) 的链,没有其他节点。
pushup(x)
Splay/LCT 学习笔记的更多相关文章
- LCT 学习笔记
LCT学习笔记 前言 自己定的学习计划看起来完不成了(两天没学东西,全在补题),决定赶快学点东西 于是就学LCT了 简介 Link/Cut Tree是一种数据结构,我们用它解决动态树问题 但是LCT不 ...
- BST,Splay平衡树学习笔记
BST,Splay平衡树学习笔记 1.二叉查找树BST BST是一种二叉树形结构,其特点就在于:每一个非叶子结点的值都大于他的左子树中的任意一个值,并都小于他的右子树中的任意一个值. 2.BST的用处 ...
- SPLAY,LCT学习笔记(六)
这应该暂时是个终结篇了... 最后在这里讨论LCT的一个常用操作:维护虚子树信息 这也是一个常用操作 下面我们看一下如何来维护 以下内容转自https://blog.csdn.net/neither_ ...
- SPLAY,LCT学习笔记(五)
这一篇重点探讨LCT的应用 例:bzoj 2631 tree2(国家集训队) LCT模板操作之一,利用SPLAY可以进行区间操作这一性质对维护懒惰标记,注意标记下传顺序和如何下传 #include & ...
- SPLAY,LCT学习笔记(四)
前三篇好像变成了SPLAY专题... 这一篇正式开始LCT! 其实LCT就是基于SPLAY的伸展操作维护树(森林)连通性的一个数据结构 核心操作有很多,我们以一道题为例: 例:bzoj 2049 洞穴 ...
- SPLAY,LCT学习笔记(一)
写了两周数据结构,感觉要死掉了,赶紧总结一下,要不都没学明白. SPLAY专题: 例:NOI2005 维修数列 典型的SPLAY问题,而且综合了SPLAY常见的所有操作,特别适合新手入门学习(比如我这 ...
- SPLAY,LCT学习笔记(三)
前两篇讲述了SPLAY模板操作,这一篇稍微介绍一下SPLAY的实际应用 (其实只有一道题,因为本蒟蒻就写了这一个) 例:bzoj 1014火星人prefix 由于本蒟蒻不会后缀数组,所以题目中给的提示 ...
- SPLAY,LCT学习笔记(二)
能够看到,上一篇的代码中有一段叫做find我没有提到,感觉起来也没有什么用,那么他的存在意义是什么呢? 接下来我们来填一下这个坑 回到我们的主题:NOI 2005维修数列 我们刚刚讨论了区间翻转的操作 ...
- LCT学习笔记
最近自学了一下LCT(Link-Cut-Tree),参考了Saramanda及Yang_Zhe等众多大神的论文博客,对LCT有了一个初步的认识,LCT是一种动态树,可以处理动态问题的算法.对于树分治中 ...
- [总结] LCT学习笔记
\(emmm\)学\(lct\)有几天了,大概整理一下这东西的题单吧 (部分参考flashhu的博客) 基础操作 [洛谷P1501Tree II] 题意 给定一棵树,要求支持 链加,删边加边,链乘,询 ...
随机推荐
- node.js 增删改查(原始)
index.js 连接数据库 const mongoose = require('mongoose') //数据库连接27017是mongodb数据库的默认端口 mongoose.connect(' ...
- PS工具的基本使用
常见的图片格式: 切片工具的使用 1.用切片选中图片 2.导出切片 3.切片悬着工具 可以选择指定 切片框 删除. 点击图层 切图 清除切片 基于参考线的切片 切图插件Cutterman
- 【算法】用c#实现自定义字符串编码及围栏解码方法
编写一个函数/方法,它接受2个参数.一个字符串和轨道数,并返回ENCODED字符串. 编写第二个函数/方法,它接受2个参数.一个编码字符串和轨道数,并返回DECODED字符串. 然后使用围栏密码对其进 ...
- [oeasy]python0029_放入系统路径_PATH_chmod_程序路径_执行原理
放入路径 回忆上次内容 上次总算可以把 sleep.py 直接执行了 sleep.py文件头部要声明好打开方式 #!/usr/bin/python3 用的是 python3 解释 sleep.py ...
- ECMAScript 是什么?
ECMAScript 是什么 简介 Ecma 标准定义了 ECMAScript 语言 ECMAScript 基于多种原始技术,最著名的是 JavaScript (Netscape) 和 JScript ...
- Oracle 删除大量表记录操作总结
By:授客 QQ:1033553122 删除表数据操作 清空所有表记录 TRUNCATE TABLE your_table_name; 或者批量删除满足条件的表记录 BEGIN LOOP DELETE ...
- Python 实现Excel和TXT文本格式之间的相互转换
Excel是一种具有强大的数据处理和图表制作功能的电子表格文件,而TXT则是一种简单通用.易于编辑的纯文本文件.将Excel转换为TXT可以帮助我们将复杂的数据表格以文本的形式保存,方便其他程序读取和 ...
- ComfyUI进阶:Comfyroll插件 (七)
前言: 学习ComfyUI是一场持久战,而Comfyroll 是一款功能强大的自定义节点集合,专为 ComfyUI 用户打造,旨在提供更加丰富和专业的图像生成与编辑工具.借助这些节点,用户可以在静态图 ...
- 关于我自己的Gui界面库完善
仓库地址:https://gitee.com/GPRO/Gui 功能说明: 解析XML, 接入AngleScript. 接下来需要做的: 因为有了WPF,MFC,HTML甚至UE5的使用经验,这里我 ...
- 开源新纪元:Llama 3.1超大杯405B跑分惊艳,首次超越GPT-4o,下载链接曝光!
开源巨擘Llama 3.1崭露头角,性能卓越引发热议 在科技界的瞩目下,Llama 3.1系列模型以其卓越的性能脱颖而出,尤其是其405B超大杯版本,在微软Azure-ML GitHub平台的多项评测 ...