浅谈splay
\(BST\)
二叉查找树,首先它是一颗二叉树,其次它里面每个点都满足以该点左儿子为根的子树里结点的值都小于自己的值,以该点右儿子为根的子树里结点的值都大于自己的值。如果不进行修改,每次查询都是\(O(logn)\)的。
\(Splay\)
\(splay\)是一种支持旋转的二叉查找树,由于旋转可以维护它的深度,使其保持平衡,所以我们又称它为平衡树。一般的平衡树支持的操作它基本都支持,不支持的比如有可持久化。所以我们不多赘述,直接讲它的特性:
旋转
\(zig和zag\)
单次旋转。若一个点是它父亲的左儿子,把它旋转上去,让它父亲成为它的右儿子,则称为\(zig\),否则称为\(zag\)。
根据下面这张图我们可以很好的理解\(zig\)和\(zag\)。

然后这两种单旋操作配合起来一共有四种双旋操作,分别是\(zig-zig\),\(zig-zag\),\(zag-zig\),\(zag-zag\)。
如果你觉得很烦,那你千万不要离开,因为本篇博客,就是来帮助你解忧的。
双旋单旋分情况讨论记不清怎么办?来来来,继续往下看,妈妈绝对不会再担心你的\(splay\)写挂了。
对于一次旋转,只会影响的四个结点,分别是\(x\)本身,\(x\)的父亲\(fa\),\(x\)的儿子\(s\),\(fa\)的父亲\(ffa\)。
设\(t(x)\)为\(x\)与其父亲的关系,左儿子为\(0\),右儿子为\(1\),那么\(t(s)=t(x)xor\) \(1\)。
第一步:把\(fa\)扳下来。
先确定\(fa\)与\(s\)的双方关系,\(fa\)在\(t(x)\)方向上认\(s\)做儿子,\(s\)认\(fa\)做父亲。然后按照此步骤确定\(x\)与\(fa\)的双方关系。
第二步:把\(x\)送上去。
确定\(x\)与\(ffa\)的双方关系。
代码如下:
int t(int u){return son[fa[u]][1]==u;}
void rotate(int u){
int ret=t(u),f=fa[u],s=son[u][ret^1];
int ffa=fa[f],ret_f=t(f);
son[f][ret]=s;if(s)fa[s]=f;//确立s与fa的关系
son[u][ret^1]=f;fa[f]=u;//确立u与fa的关系
fa[u]=ffa;if(ffa)son[ffa][ret_f]=u;//确立u与ffa的关系
}
至此,单旋操作就没了,是不是非常简单呢?
\(splay\)
\(splay\)操作就是让一个点\(x\)一直旋转一直旋转直到它到根为止。有单旋和双旋两种操作,单旋就是直接\(while\)循环调用上面那段代码就行了,双旋有四种情况,但是总的来说也只有两种。
当\(t(x)==t(fa)\)时,那就先单旋\(fa\),否则单旋一次\(x\)。
不管上面那个条件满不满足,都在第二次单旋一次\(x\)。
代码如下:
void splay(int u){
while(fa[u]){//有父亲就不是根
if(fa[fa[u]]){//可以双旋
if(t(fa[u])==t(u))rotate(fa[u]);
else rotate(u);//如上所述
}rotate(u);
}root=u;//旋转到根之后更新根
}
至此,\(splay\)的旋转操作就到此为止了,怎么样,是不是很简单呢?
哦对了,\(splay\)的复杂度十分玄学,在势能分析上来说,应该是\(log\)的,但是保持这个势能需要多多\(splay\),插入要\(splay\),删除也要\(splay\)。
插入
找到一个整个树里面权值最接近插入结点权值的点,然后把要插入的点给它做儿子,然后\(splay\)到根。
删除
把要删除的点\(splay\)到根,然后把它左儿子子树里最大的值旋到根的左儿子处,断开要删除的点的周边所有关系,把右子树的根接在左子树最大值右儿子处即可。
若需区间删除,则把\(l-1splay\)到根,把\(r+1splay\)到根的右儿子处,然后整个右儿子的左子树全部扔掉即可。
大多数时刻区间翻转区间加等操作都是这样,把要处理的区间这样放在根的右儿子的左子树处,然后直接打标记即可,这里我们就不多说了。
模板:https://www.cnblogs.com/AKMer/p/9985277.html
区间操作模板:https://www.cnblogs.com/AKMer/p/9987089.html
浅谈splay的更多相关文章
- 浅谈splay(点的操作)
浅谈splay(点的操作) 一.基本概念 splay本质:二叉查找树 特点:结点x的左子树权值都小于x的权值,右子树权值都大于x的权值 维护信息: 整棵树:root 当前根节点 sz书上所有结点编号 ...
- 浅谈splay的双旋
昨晚终于明白了splay双旋中的一些细节,今日整理如下 注:题目用的2002HNOI营业额统计,测试结果均来及codevs 网站的评测结果 http://codevs.cn/problem/1296/ ...
- 简析平衡树(三)——浅谈Splay
前言 原本以为\(Treap\)已经很难了,学习了\(Splay\),我才知道,没有最难,只有更难.(强烈建议先去学一学\(Treap\)再来看这篇博客) 简介 \(Splay\)是平衡树中的一种,除 ...
- Lct浅谈
Lct浅谈 1.对lct的认识 首先要知道$lct$是什么.$lct$的全称为$link-cut-tree$.通过全称可以看出,这个数据结构是维护树上的问题,并且是可以支持连边断边操作.$lct$ ...
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
随机推荐
- JavaScript---循环与闭包
循环与闭包 先看一个demo <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...
- 036——VUE中表单控件处理之动态绑定文章的属性的处理方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 连接GitHub的方法
连接到GitHub 首先在本地创建 ssh key: ssh-keygen -t rsa -C "your_email@youremail.com" 后面的 your_email@ ...
- Java复习7.输入输出流
Java复习7.输入输出流 20131005 前言: Java中涉及数据的读写,都是基于流的,这一块的知识相当重要,而且在Java中的数据,char字符是16bit的,所以存在字节流和字符流的区别.如 ...
- 【lightoj-1024】Eid (高精度)
[题意] 给定n个数,求这n个数的最小公倍数. [题解] 最小公倍数当然不能按常规方法来求,因为最大的数将近是10000^1000级别的.然鹅最小公倍数怎么搞呢? 这里发现了一个规律: 4 5 6 3 ...
- week10《java程序设计》作业总结
week10<java程序设计>作业总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 答:: 2. 书面作业 本次PTA作业题集异常 1. 常用异常 ...
- Linux:grub密码设置与修改
grub密码设置与修改 默认GRUB启动参数可以的进入单用户模式从而修改root密码,如果想要给GRUB菜单设置密码,可以修改/etc/grub.conf文件 (/boot/grub/grub.con ...
- 关于PHP页面显示乱码问题的解决
关于PHP页面显示乱码问题的解决 网页乱码一直是网络编程高手都头痛的问题,我是一个PHP Web编程的初学者,学习当中也遇到了这个问题,查找了相关的资源,总结如下: 一般的中文编码:gb2312,gb ...
- Android程序员学WEB前端(5)-HTML(5)-框架集-Sublime
转载请注明出处:http://blog.csdn.net/iwanghang/article/details/76576279 觉得博文有用,请点赞,请评论,请关注,谢谢!~ 框架集: index7. ...
- CS231n课程笔记翻译3:线性分类笔记
译者注:本文智能单元首发,译自斯坦福CS231n课程笔记Linear Classification Note,课程教师Andrej Karpathy授权翻译.本篇教程由杜客翻译完成,巩子嘉和堃堃进行校 ...