[复习]平衡树splay
明天要考试了……
出来写一个splay的复习总结。
怕忘……
^废话^
以下内容学习自yyb大神的博客,
由于yyb大神内容不全,
部分是博主本人自行脑补。。。
这个模板还是比较全的^-^
^又是一堆不是废话的废话^
Splay的核心就是旋转了。
rotate操作:将x旋转为它祖先节点的子节点。
inline void rotate(long long x)//基本旋转操作:旋转x
{
long long y=t[x].fa,z=t[y].fa,k=t[y].ch[]==x;//y是x的父节点,z是x的祖先节点,
//k存储x是y的哪一个儿子
t[z].ch[t[z].ch[]==y]=x;
t[x].fa=z;//祖为父:我变成我爷爷的儿子,我管我爷爷喊爸爸
t[y].ch[k]=t[x].ch[k^];
t[t[x].ch[k^]].fa=y;//子为孙:我儿子过继给我爸爸,我儿子管我爸爸喊爹
t[x].ch[k^]=y;
t[y].fa=x;//父为子:我爸爸变成我儿子,我爸爸管我喊爹
t[y].size=t[t[y].ch[]].size+t[t[y].ch[]].size+t[y].cnt;//更新节点规模
//size存储以该节点为根节点的子树的大小(包括自身)
t[x].size=t[t[x].ch[]].size+t[t[x].ch[]].size+t[x].cnt;//由于此时y是x的子节点,所以先y后x
}
涉及伦理问题……引起不适敬请原谅
splay操作:将x旋转为goal的子节点
inline void splay(long long x,long long goal)//splay操作:将x旋转为goal的子节点
{
while(t[x].fa!=goal)//若x的父节点不是目标节点
{
long long y=t[x].fa,z=t[y].fa;//取出父节点和祖先节点
if(z!=goal)//若祖先节点依旧不是目标节点,那么意味着我们至少需要旋转两次
(t[z].ch[]==y)^(t[y].ch[]==x)?rotate(x):rotate(y);
//为了打乱原本平衡树上存在的一条链从而防止被卡,若x、y、z在同一条线上,先转y
rotate(x);//无论之前转了y还是x或者是没有转,我们都需要再转一次x
}
if(!goal)root=x;//更新根节点
}
insert操作:插入一个数x,使平衡树仍然保持平衡
inline void insert(long long x)//插入操作:插入一个数x,使平衡树仍然保持平衡
{
long long u=root,fa=;//从根节点开始搜,记得存储fa以更新x的节点信息中的fa
while(u&&t[u].data!=x)//u仍然存在且当前节点u不等于目标节点,迭代向下查找。
{
fa=u;
u=t[u].ch[x>t[u].data];//x小于当前节点信息,向左查找,否则向右查找。(利用平衡树本身性质)
}
if(u)t[u].cnt++;//如果本身存在该节点,该节点个数加一
else //否则新建一个节点(各个信息都要新建)
{
u=++tot;
if(fa)t[fa].ch[x>t[fa].data]=u;
t[u].ch[]=t[u].ch[]=;
t[tot].fa=fa;
t[tot].data=x;
t[tot].cnt=;
t[tot].size=;
}
splay(u,);
}
find操作:找到元素x并将它旋转为根节点
inline void find(long long x)//查找操作:找到元素x并将它旋转为根节点
{
long long u=root;//u是当前节点,从根节点开始搜索。
if(!u)return ;//如果没有根节点,即没有树:查询无效。
while(t[u].ch[x>t[u].data]&&x!=t[u].data)//继续迭代向下查找x
u=t[u].ch[x>t[u].data];
splay(u,);//转上去
}
nxt操作:查询前驱或后继
inline long long nxt(long long x,long long jud)//查询操作:查询前驱或后继
{ //(jud为0时表示查询前驱,jud为1时表示查询后继)
find(x);//找到x并把他(或者和它最接近的那个点)转到根节点
long long u=root;
if(t[u].data>x&&jud)return u;
if(t[u].data<x&&!jud)return u;//这两句话针对查询的x本身不在平衡树中
u=t[u].ch[jud];//若该节点已经被旋转为根节点,前驱是它左子树最右边的儿子,后驱是它右子树最左边的儿子。
while(t[u].ch[jud^])u=t[u].ch[jud^];
return u;
}
delet操作:删掉某一个节点
inline void delet(long long x)//删除操作:删掉某一个节点
{
long long pre=nxt(x,);
long long nt=nxt(x,);//分别查询前驱和后继并存储
splay(pre,),splay(nt,pre);//把前驱转成根节点,把后继转成根节点的子节点。
//分析可得此时nt是pre的右儿子,x是nt的左儿子且x没有子树
long long res=t[nt].ch[];
if(t[res].cnt>)
{
t[res].cnt--;//若该节点不止一个,删掉一个
splay(res,);//并把该节点旋转至根节点
}
else t[nt].ch[]=;//否则直接把它扔掉(nt的左儿子指向空)
}
k_th操作:查询已插入的节点中第k大的数
inline long long k_th(long long x)//第k大操作:查询已插入的节点中第k大的数
{
long long u=root;//临时节点u
if(t[u].size<x)return ;//若该点的规模小于x,即不可能存在第x大的数,返回0
while()
{
int y=t[u].ch[];//取出左儿子方便查询规模
if(x>t[y].size+t[u].cnt)//如果所查询的数大于左儿子的规模
{
x-=t[y].size+t[u].cnt;//往右找,查询的第k大数即是右儿子中x-t[y].size+t[u].cnt
u=t[u].ch[];
}
else
if(t[y].size>=x) u=y;//如果儿子查询
else return t[u].data;//
}
}
谢谢您的一波关注好评阅读评论走起~
[复习]平衡树splay的更多相关文章
- Tyvj P1729 文艺平衡树 Splay
题目: http://tyvj.cn/p/1729 P1729 文艺平衡树 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 此为平衡树系列第二道:文艺平衡树 ...
- hiho #1329 : 平衡树·Splay
#1329 : 平衡树·Splay 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. ...
- 【BZOJ3224】Tyvj 1728 普通平衡树 Splay
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...
- BZOJ3224/洛谷P3391 - 普通平衡树(Splay)
BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...
- Hihocoder 1329 平衡树·Splay(平衡树)
Hihocoder 1329 平衡树·Splay(平衡树) Description 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. 小Hi:怎么了? 小Ho:小H ...
- 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay
[阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...
- luoguP3391[模板]文艺平衡树(Splay) 题解
链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...
- 平衡树——splay 三
前文链接: 平衡树--splay 一 - yi_fan0305 - 博客园 (cnblogs.com) 平衡树--splay 二 - yi_fan0305 - 博客园 (cnblogs.com) 再补 ...
- 平衡树——splay 二
上文传送门:平衡树--splay 一 - yi_fan0305 - 博客园 (cnblogs.com) OK,我们继续上文,来讲一些其他操作. 七.找排名为k的数 和treap的操作很像,都是通过比较 ...
随机推荐
- ashx后门[转]
https://www.cnblogs.com/Fluorescence-tjy/p/9855828.html 一.标准ASPX一句话木马 .NET平台下的一句话木马则百年不变,最常见的当属下面这句 ...
- Python3 From Zero——{最初的意识:006~数据编码与处理}
一.读写CSV数据: #!/usr/bin/env python3 #-*- coding=utf8 -*- import csv with open('kxtx.csv', 'rt') as f: ...
- Spring AOP源码分析(二):AOP的三种配置方式与内部解析实现
AOP配置 在应用代码中,可以通过在spring的XML配置文件applicationContext.xml或者基于注解方式来配置AOP.AOP配置的核心元素为:pointcut,advisor,as ...
- 牛客D-Where are you /// kruskal+tarjan找无向图内的环
题目大意: https://ac.nowcoder.com/acm/contest/272/D 在一个无向图中,给定一个起点,从起点开始走遍图中所有点 每条边有边权wi,表示第一次经过该道路时的花费( ...
- ARM多核处理器启动过程分析
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/qianlong4526888/article/details/27695173 说明: 该流程图依照 ...
- libevent的使用 32位 64位
前段时间一个项目需要用到高并发的服务,想着自己应该可以写一个,windwos 上使用完成端口实现,写完之后,测试感觉没什么问题,可是一上线各种各样的问题,初步怀疑是底层网路库的问题,于是决定更换网络库 ...
- SQL SERVER 2008R2 执行大脚本文件时,提示“内存不足”的解决办法
我把一个数据库的架构及数据都已脚本的方式拷贝下来,再去新建一个数据库想把脚本执行一下,但提示如下错误: 问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是 ...
- CSS动画库——animate.css的使用
Animate.css是一款强大的CSS3动画库 官网地址:https://daneden.github.io/animate.css/ 使用方法如下所示: (1)下载animate.css 下载地址 ...
- 关于FR4板一些重复的数据
介电常数:4.2-4.7 信号传输速度:表层 140~170 ps/inch, 内层 180 ps/inch
- 【转载】opencl中设备内存
地址空间限定符 一般的内核代码中,里面的内核参数或声明变量时,都会有地址空间限定符 地址空间限定符,地址空间限定符的主要作用是指出数据应该保存在哪个地方 地址空间限定符有4个: 全局内存: 限定符:_ ...