明天要考试了……

出来写一个splay的复习总结。

怕忘……

^废话^


以下内容学习自yyb大神的博客,

由于yyb大神内容不全,

部分是博主本人自行脑补。。。

这个模板还是比较全的^-^

^又是一堆不是废话的废话^


Splay的核心就是旋转了。

rotate操作:将x旋转为它祖先节点的子节点。

  1. inline void rotate(long long x)//基本旋转操作:旋转x
  2. {
  3. long long y=t[x].fa,z=t[y].fa,k=t[y].ch[]==x;//y是x的父节点,z是x的祖先节点,
  4. //k存储x是y的哪一个儿子
  5. t[z].ch[t[z].ch[]==y]=x;
  6. t[x].fa=z;//祖为父:我变成我爷爷的儿子,我管我爷爷喊爸爸
  7. t[y].ch[k]=t[x].ch[k^];
  8. t[t[x].ch[k^]].fa=y;//子为孙:我儿子过继给我爸爸,我儿子管我爸爸喊爹
  9. t[x].ch[k^]=y;
  10. t[y].fa=x;//父为子:我爸爸变成我儿子,我爸爸管我喊爹
  11. t[y].size=t[t[y].ch[]].size+t[t[y].ch[]].size+t[y].cnt;//更新节点规模
  12. //size存储以该节点为根节点的子树的大小(包括自身)
  13. t[x].size=t[t[x].ch[]].size+t[t[x].ch[]].size+t[x].cnt;//由于此时y是x的子节点,所以先y后x
  14. }

涉及伦理问题……引起不适敬请原谅

splay操作:将x旋转为goal的子节点

  1. inline void splay(long long x,long long goal)//splay操作:将x旋转为goal的子节点
  2. {
  3. while(t[x].fa!=goal)//若x的父节点不是目标节点
  4. {
  5. long long y=t[x].fa,z=t[y].fa;//取出父节点和祖先节点
  6. if(z!=goal)//若祖先节点依旧不是目标节点,那么意味着我们至少需要旋转两次
  7. (t[z].ch[]==y)^(t[y].ch[]==x)?rotate(x):rotate(y);
  8. //为了打乱原本平衡树上存在的一条链从而防止被卡,若x、y、z在同一条线上,先转y
  9. rotate(x);//无论之前转了y还是x或者是没有转,我们都需要再转一次x
  10. }
  11. if(!goal)root=x;//更新根节点
  12. }

insert操作:插入一个数x,使平衡树仍然保持平衡

  1. inline void insert(long long x)//插入操作:插入一个数x,使平衡树仍然保持平衡
  2. {
  3. long long u=root,fa=;//从根节点开始搜,记得存储fa以更新x的节点信息中的fa
  4. while(u&&t[u].data!=x)//u仍然存在且当前节点u不等于目标节点,迭代向下查找。
  5. {
  6. fa=u;
  7. u=t[u].ch[x>t[u].data];//x小于当前节点信息,向左查找,否则向右查找。(利用平衡树本身性质)
  8. }
  9. if(u)t[u].cnt++;//如果本身存在该节点,该节点个数加一
  10. else //否则新建一个节点(各个信息都要新建)
  11. {
  12. u=++tot;
  13. if(fa)t[fa].ch[x>t[fa].data]=u;
  14. t[u].ch[]=t[u].ch[]=;
  15. t[tot].fa=fa;
  16. t[tot].data=x;
  17. t[tot].cnt=;
  18. t[tot].size=;
  19. }
  20. splay(u,);
  21. }

find操作:找到元素x并将它旋转为根节点

  1. inline void find(long long x)//查找操作:找到元素x并将它旋转为根节点
  2. {
  3. long long u=root;//u是当前节点,从根节点开始搜索。
  4. if(!u)return ;//如果没有根节点,即没有树:查询无效。
  5. while(t[u].ch[x>t[u].data]&&x!=t[u].data)//继续迭代向下查找x
  6. u=t[u].ch[x>t[u].data];
  7. splay(u,);//转上去
  8. }

nxt操作:查询前驱或后继

  1. inline long long nxt(long long x,long long jud)//查询操作:查询前驱或后继
  2. { //(jud为0时表示查询前驱,jud为1时表示查询后继)
  3. find(x);//找到x并把他(或者和它最接近的那个点)转到根节点
  4. long long u=root;
  5. if(t[u].data>x&&jud)return u;
  6. if(t[u].data<x&&!jud)return u;//这两句话针对查询的x本身不在平衡树中
  7. u=t[u].ch[jud];//若该节点已经被旋转为根节点,前驱是它左子树最右边的儿子,后驱是它右子树最左边的儿子。
  8. while(t[u].ch[jud^])u=t[u].ch[jud^];
  9. return u;
  10. }

delet操作:删掉某一个节点

  1. inline void delet(long long x)//删除操作:删掉某一个节点
  2. {
  3. long long pre=nxt(x,);
  4. long long nt=nxt(x,);//分别查询前驱和后继并存储
  5. splay(pre,),splay(nt,pre);//把前驱转成根节点,把后继转成根节点的子节点。
  6. //分析可得此时nt是pre的右儿子,x是nt的左儿子且x没有子树
  7. long long res=t[nt].ch[];
  8. if(t[res].cnt>)
  9. {
  10. t[res].cnt--;//若该节点不止一个,删掉一个
  11. splay(res,);//并把该节点旋转至根节点
  12. }
  13. else t[nt].ch[]=;//否则直接把它扔掉(nt的左儿子指向空)
  14. }

k_th操作:查询已插入的节点中第k大的数

  1. inline long long k_th(long long x)//第k大操作:查询已插入的节点中第k大的数
  2. {
  3. long long u=root;//临时节点u
  4. if(t[u].size<x)return ;//若该点的规模小于x,即不可能存在第x大的数,返回0
  5. while()
  6. {
  7. int y=t[u].ch[];//取出左儿子方便查询规模
  8. if(x>t[y].size+t[u].cnt)//如果所查询的数大于左儿子的规模
  9. {
  10. x-=t[y].size+t[u].cnt;//往右找,查询的第k大数即是右儿子中x-t[y].size+t[u].cnt
  11. u=t[u].ch[];
  12. }
  13. else
  14. if(t[y].size>=x) u=y;//如果儿子查询
  15. else return t[u].data;//
  16. }
  17. }

谢谢您的一波关注好评阅读评论走起~

[复习]平衡树splay的更多相关文章

  1. Tyvj P1729 文艺平衡树 Splay

    题目: http://tyvj.cn/p/1729 P1729 文艺平衡树 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 此为平衡树系列第二道:文艺平衡树 ...

  2. hiho #1329 : 平衡树·Splay

    #1329 : 平衡树·Splay 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. ...

  3. 【BZOJ3224】Tyvj 1728 普通平衡树 Splay

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...

  4. BZOJ3224/洛谷P3391 - 普通平衡树(Splay)

    BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...

  5. Hihocoder 1329 平衡树·Splay(平衡树)

    Hihocoder 1329 平衡树·Splay(平衡树) Description 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. 小Hi:怎么了? 小Ho:小H ...

  6. 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay

    [阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...

  7. luoguP3391[模板]文艺平衡树(Splay) 题解

    链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...

  8. 平衡树——splay 三

    前文链接: 平衡树--splay 一 - yi_fan0305 - 博客园 (cnblogs.com) 平衡树--splay 二 - yi_fan0305 - 博客园 (cnblogs.com) 再补 ...

  9. 平衡树——splay 二

    上文传送门:平衡树--splay 一 - yi_fan0305 - 博客园 (cnblogs.com) OK,我们继续上文,来讲一些其他操作. 七.找排名为k的数 和treap的操作很像,都是通过比较 ...

随机推荐

  1. 基于Netty的RPC架构学习笔记(七):netty学习之心跳

    文章目录 idleStateHandler netty3

  2. ncurses库的介绍与安装

    Frm: http://blog.csdn.net/Mary_Jane/article/details/50769631 介绍 ncurses(new curses)是一套编程库,它提供了一系列的函数 ...

  3. day 89 DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件

    DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件   本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...

  4. C++数据类型之实型(浮点型)&科学计数法

    实型(浮点型) **作用**:用于==表示小数== 浮点型变量分为两种: 1. 单精度float 2. 双精度double 两者的**区别**在于表示的有效数字范围不同. float类型数据,需在数据 ...

  5. 17-Ubuntu-文件和目录命令-切换目录-相对路径和绝对路径

    1.相对路径: 在输入路径时,最前面不是/或者~,表示相对当前目录所在的目录位置. 例:当前桌面目录下,通过相对路径切换到桌面目录下的Entertainment目录 2.绝对路径: 在输入路径时,最前 ...

  6. Python+Django+SAE系列教程6-----本地配置Django

    前五章.我们介绍了Python的语法,本章開始介绍Django. Python的Web框架有非常多,有Django.web2py.tornado.web.py等.我们这里选 则Django.至于这些框 ...

  7. Ubuntu环境下Postgres源码文件编译安装步骤

    step1:官网下载postgres源码 URL:https://www.postgresql.org/ftp/source/ step2:解压源码文件 tar -zxvf postgresql-12 ...

  8. STM32---初学者用库函数好还是直接对寄存器操作比较好

    引用:http://blog.csdn.net/u010349006/article/details/416 首先,两个都是C语言.从51过渡过来的话,就先说寄存器操作.每个MCU都有自己的寄存器,5 ...

  9. 21-1字符串相关api

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. MySQL 07章_子查询

    子查询就是查询中还可以嵌套其他的查询,通常是内层查询的结果作为外层查询的条件来使用 执行循序,自内向外依次执行 一.内层查询返回“单列单行”的结果 -- 1.查询宋江的出生日期 SELECT TIME ...