\(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的更多相关文章

  1. 浅谈splay(点的操作)

    浅谈splay(点的操作) 一.基本概念 splay本质:二叉查找树 特点:结点x的左子树权值都小于x的权值,右子树权值都大于x的权值 维护信息: 整棵树:root 当前根节点  sz书上所有结点编号 ...

  2. 浅谈splay的双旋

    昨晚终于明白了splay双旋中的一些细节,今日整理如下 注:题目用的2002HNOI营业额统计,测试结果均来及codevs 网站的评测结果 http://codevs.cn/problem/1296/ ...

  3. 简析平衡树(三)——浅谈Splay

    前言 原本以为\(Treap\)已经很难了,学习了\(Splay\),我才知道,没有最难,只有更难.(强烈建议先去学一学\(Treap\)再来看这篇博客) 简介 \(Splay\)是平衡树中的一种,除 ...

  4. Lct浅谈

    Lct浅谈 1.对lct的认识 ​ 首先要知道$lct$是什么.$lct$的全称为$link-cut-tree$.通过全称可以看出,这个数据结构是维护树上的问题,并且是可以支持连边断边操作.$lct$ ...

  5. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  6. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  7. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  8. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  9. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

随机推荐

  1. 快速切题 poj 3026 Borg Maze 最小生成树+bfs prim算法 难度:0

    Borg Maze Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8905   Accepted: 2969 Descrip ...

  2. 重温MVC基础入门

    重温MVC基础入门   简介 本文主要是作者回顾MVC基础的文章,整合个人认为基础且重点的信息,通过简单实践进行复习. 相关代码地址:https://github.com/OtherRuan/Revi ...

  3. python之阶乘的小例子

    现在自己写阶乘是这个样子的 def f(x): return x * f(x-1) if x >1 else 1 后来无意中看到耗子的一篇<Python程序员的进化>的文章, 感脚这 ...

  4. 第8课:异常处理、面向对象编程、发送邮件、url编码

    1. 异常处理 import traceback import pymysql import requests def calc(a, b): res = a / b return res def m ...

  5. VM遇到的问题参考

    http://saturn.blog.51cto.com/184463/950731/

  6. cmakelist

    cmake 添加头文件目录,链接动态.静态库 罗列一下cmake常用的命令. CMake支持大写.小写.混合大小写的命令. 1. 添加头文件目录INCLUDE_DIRECTORIES 语法: incl ...

  7. Android程序员学WEB前端(5)-HTML(5)-框架集-Sublime

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/76576279 觉得博文有用,请点赞,请评论,请关注,谢谢!~ 框架集: index7. ...

  8. VMWare的共享文件的安装指南

    引言:笔者这几天基于CentOS 7的精简版按照了一个虚拟机,悲催的是没有图形界面,但是非常需要共享文件的工作,在宿主机以及虚拟机之间实现文件共享,本文将描述如何实现此操作. VMWare菜单按照VM ...

  9. [置顶] Android 状态栏那些小坑?

    背景:因为之前老板上次问我我们的app能不能自定义上面的状态栏我说可以啊!当时没管,今天试了下果然很多坑,之前github上也有很多大佬写了一个开源库有兴趣的可以点进去看下支持DrawLayout沉侵 ...

  10. python爬虫入门(3)-环境搭建

    下载集成包 链接:http://pan.baidu.com/s/1pKD2zBP 密码:f75b 这里采用python2.7.9   安装步骤:1.安装python2.7(默认安装即可) 2.打开“运 ...