SPLAY or SPALY ?
写在前面:
由我们可爱的Daniel Sleator和Robert Tarjan提出的一种数据结构,平衡树的一种,本质是二叉树。
至于到底是splay还是spaly,我认为可能splay更对一些
毕竟splay是有实意的单词,更有可能一点。而且WIKI百科页也是splay
以下是本人学习splay的一点过程,请多指教喽
SPLAY
那么我在这里复习整理一下spaly的代码相关吧
例题:http://www.lydsy.com/JudgeOnline/problem.php?id=3224
参考博客:http://blog.csdn.net/clove_unique/article/details/50636361
#include<cstdio>
#define maxn 500100
using namespace std;
int root,N,tot;
inline int read(){
register int x=,t=;
register char ch=getchar();
while((ch<''||ch>'')&&ch!='-')ch=getchar();
if(ch=='-'){t=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-;ch=getchar();}
return x*t;
}
struct node{
int ch[],ff,cnt,val,sum;
}t[maxn];
void pushup(int u){
t[u].sum=t[t[u].ch[]].sum+t[t[u].ch[]].sum+t[u].cnt;
}
void rotate(int x){
register int y=t[x].ff;
register int z=t[y].ff;
register int k=t[y].ch[]==x;
t[z].ch[t[z].ch[]==y]=x;t[x].ff=z;
t[y].ch[k]=t[x].ch[k^];t[t[x].ch[k^]].ff=y;
t[x].ch[k^]=y;t[y].ff=x;
pushup(y),pushup(x);
}
void splay(int x,int goal){
while(t[x].ff!=goal){
int y=t[x].ff;
int z=t[y].ff;
if(z!=goal)
(t[y].ch[]==x)^(t[z].ch[]==y)?rotate(x):rotate(y);
rotate(x);
}
if(goal==)
root=x;
}
void insert(int x){
int u=root,ff=;
while(u&&t[u].val!=x){
ff=u;
u=t[u].ch[x>t[u].val];
}
if(u)
t[u].cnt++;
else{
u=++tot;
if(ff)
t[ff].ch[x>t[ff].val]=u;
t[tot].ch[]=;
t[tot].ch[]=;
t[tot].ff=ff;t[tot].val=x;
t[tot].cnt=t[tot].sum=;
}
splay(u,);
}
void find(int x){
int u=root;
if(!u)return;
while(t[u].ch[x>t[u].val]&&x!=t[u].val)
u=t[u].ch[x>t[u].val];
splay(u,);
}
int next(int x,int f){
find(x);
int u=root;
if((t[u].val>x&&f)||(t[u].val<x&&!f))return u;
u=t[u].ch[f];
while(t[u].ch[f^])u=t[u].ch[f^];
return u;
}
void del(int x){
int la=next(x,);
int ne=next(x,);
splay(la,),splay(ne,la);
int d=t[ne].ch[];
if(t[d].cnt>){
t[d].cnt--;
splay(d,);
}
else
t[ne].ch[]=;
}
int K_th(int x){
int u=root;
if(t[u].sum<x)
return ;
while(){
int y=t[u].ch[];
if(x>t[y].sum+t[u].cnt){
x-=t[y].sum+t[u].cnt;
u=t[u].ch[];
}
else if(t[y].sum>=x)
u=y;
else
return t[u].val;
}
}
int main(){
insert(-);
insert(+);
N=read();
while(N--){
int opt=read();
if(opt==)insert(read());
else if(opt==)del(read());
else if(opt==){
find(read());
printf("%d\n",t[t[root].ch[]].sum);
}
else if(opt==)printf("%d\n",K_th(read()+));
else if(opt==)printf("%d\n",t[next(read(),)].val);
else if(opt==)printf("%d\n",t[next(read(),)].val);
}
return ;
}
上面那份代码其实是洛谷上的。。。本来想自己写的,但是怎么调都过不去5555(;´д`)ゞ
算了吧,既然抄了代码就要抄的明明白白,这里让我们看看splay到底是怎么维护的吧
首先是一些基本操作:
1.rotate

就是这个东西,保证了二叉树储存的元素顺序不变,大小顺序不变,总之转它就对了。
void rotate(int x){
register int y=t[x].ff;
register int z=t[y].ff;
register int k=t[y].ch[]==x;
t[z].ch[t[z].ch[]==y]=x;t[x].ff=z;
t[y].ch[k]=t[x].ch[k^];t[t[x].ch[k^]].ff=y;
t[x].ch[k^]=y;t[y].ff=x;
pushup(y),pushup(x);
}
2.splay
splay是依靠平均操作来降低复杂度的,其实有点玄学,splay这个操作就是要把每次查询和修改的中心重新改变成根,
在这个过程中尽可能的让树的大小平衡,即尽可能打断原先树上存在的链,把他们压成树。。。
反正挺神的,记住写双旋时有先后就对了,尽量让树平衡。
void splay(int x,int goal){
while(t[x].ff!=goal){
int y=t[x].ff;
int z=t[y].ff;
if(z!=goal)
(t[y].ch[]==x)^(t[z].ch[]==y)?rotate(x):rotate(y);
rotate(x);
}
if(goal==)
root=x;
}
em。。。接下来挑一些重点(我蒙过的)讲吧。。。
3.del
删除操作,为了精确定位我们想删掉的那个点,我们选择找到他的前驱,旋到根上,再找他的后继,旋到前驱下面
这样的话这个点只能在后继的左儿子上了
但是如果这个点没有前驱和后继岂不是药丸
SPLAY or SPALY ?的更多相关文章
- [BZOJ4825][HNOI2017]单旋spaly
BZOJ Luogu 题目太长了,就不放了. 题解 首先声明一点,无论是splay还是spaly,插入一个新的元素,都要rotate到根!所以说题目也算是给了一个错误示范吧. 我们发现把最值旋转到根并 ...
- [BZOJ4825][HNOI2017]单旋(线段树+Splay)
4825: [Hnoi2017]单旋 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 667 Solved: 342[Submit][Status][ ...
- bzoj4825 [Hnoi2017]单旋
Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...
- BZOJ:4825: [Hnoi2017]单旋
Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...
- HNOI2017 单旋
题目描述 网址:https://www.luogu.org/problemnew/show/3721 大意: 有一颗单旋Splay(Spaly),以key值为优先度,总共有5个操作. [1] 插入一个 ...
- [HNOI 2017]单旋
Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的 ...
- bzoj P4825 [Hnoi2017]单旋——solution
Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的 ...
- 【刷题】BZOJ 4825 [Hnoi2017]单旋
Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...
- bzo j4825 [Hnoi2017]单旋
Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的 ...
随机推荐
- Linux环境变量设置命令export(转)
Linux export命令用于设置或显示环境变量. 在shell中执行程序时,shell会提供一组环境变量.export可新增,修改或删除环境变量,供后续执行的程序使用.export的效力仅及于该次 ...
- ERROR: mount point </.alt.rootd3_EISMar14/opt/oracle/product/10.2> is already in use
在给solaris系统升级的时候,用lu方法遇到下面的错误. -bash-3.2# lumount rootd3_EISMar14 ERROR: mount point </.alt.rootd ...
- MVC.Net5:添加Tinymce的图片上传功能
Tinymce是目前几个主流的Web文本编辑器之一,不过它的图片上传功能是要收费的,而其它几个免费的上传图片的插件支持的都是PHP.那么就只能自己动手写一个了(源代码下载). 准备工作如下:1. ...
- HDU 4526
DP. 设状态dp[i][j]表示j辆车后还剩余i个人的花费,枚举一个车的座位k,加上剩下人数i,注意i+k不能超过n,就很容易dp了. #include <iostream> #incl ...
- WEB开发面试题
1.HTML的全称: 2.HTML的结构: 3.经常使用标签: 4.CSS的全称: 5.CSS的作用: 6.CSS中创建Class的语法: ...
- 保护眼睛-eclipse黑色背景设置
eclipse中java编辑器颜色改动,适合程序员人群: 长时间编码,眼睛是有非常大负担的,特别是使用eclipse,它自带的java编辑器背景色是刺眼的白色.代码颜色基本是黑色,这样一个编辑器里白色 ...
- Windows移动开发(五)——初始XAML
关于详细的基本功就先说这么多.后面遇到再补充说明,前面说的都是一些代码和原理方面的东西.接下来说的会有界面和代码结合,会有成就感,由于能真正的做出东西来了. Windows移动开发包含Windows ...
- nginx启动访问
修改配置文件后,查看配置是否ok 以下是有错误的 以下是ok的 nginx/sbin/nginx -t 启动查询: /usr/local/nginx/sbin/nginx -c /usr/local/ ...
- Bean Query 改动Bug的版本号(1.0.1)已公布
改动内容: 修复输入对象被排序的属性不存在或者为Null时出错的bug 在Maven项目中引用 <dependency> <groupId>cn.jimmyshi</gr ...
- HDU 2110-Crisis of HDU(母函数)
Crisis of HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...