写在前面:
由我们可爱的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 ?的更多相关文章

  1. [BZOJ4825][HNOI2017]单旋spaly

    BZOJ Luogu 题目太长了,就不放了. 题解 首先声明一点,无论是splay还是spaly,插入一个新的元素,都要rotate到根!所以说题目也算是给了一个错误示范吧. 我们发现把最值旋转到根并 ...

  2. [BZOJ4825][HNOI2017]单旋(线段树+Splay)

    4825: [Hnoi2017]单旋 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 667  Solved: 342[Submit][Status][ ...

  3. bzoj4825 [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...

  4. BZOJ:4825: [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...

  5. HNOI2017 单旋

    题目描述 网址:https://www.luogu.org/problemnew/show/3721 大意: 有一颗单旋Splay(Spaly),以key值为优先度,总共有5个操作. [1] 插入一个 ...

  6. [HNOI 2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的 ...

  7. bzoj P4825 [Hnoi2017]单旋——solution

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的 ...

  8. 【刷题】BZOJ 4825 [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...

  9. bzo j4825 [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的 ...

随机推荐

  1. [转]使用代码去描述WCF配置文件

    转自:使用代码去描述WCF配置文件 在应用程序部署的时候,WCF客户端因为服务器地址的变化,需要修改程序配置文件的地址URL,手动修改很不方便,还会造成错误,所以尽量把描述WCF配置文件的配置使用代码 ...

  2. maven出现不再支持源选项 1.5。请使用 1.6 或更高版本

    maven出现不再支持源选项 1.5.请使用 1.6 或更高版本 学习了:http://blog.csdn.net/sosous/article/details/78312867 错误: [ERROR ...

  3. Uva 1331 - Minimax Triangulation(最优三角剖分 区间DP)

    题目大意:依照顺时针或者逆时针的顺序给出多边的点,要将这个多边形分解成n-2个三角形,要求使得这些三角行中面积最大的三角形面积尽量小,求最小值. 思路:用区间DP能够非常方便解决,多边形可能是凹边形, ...

  4. SegmentFault 巨献 1024 程序猿游戏「红岸的呼唤」第一天任务攻略

    今天一不小心在微博上看到了SegmentFault的一条微博: 眼看今天就要过去了,那在这里说一下我的解题过程(事实上大家都知道了吧-=). 高速传送门:http://segmentfault.com ...

  5. 【Linux】Ubuntu 开机默认亮度改动方法

    换了ubuntu 之后.发现开机屏幕都是"最大亮度",每次都要到设置中手动调节,非常麻烦.于是想到去改动这个设置.Google一通,别人可行的办法到我这就没用了.郁闷.最后是在st ...

  6. 【译文】利用STAN做贝叶斯回归分析:Part 2 非正态回归

    [译文]利用STAN做贝叶斯回归分析:Part 2 非正态回归 作者 Lionel Hertzogn 前一篇文章已经介绍了怎样在R中调用STAN对正态数据进行贝叶斯回归.本文则将利用三个样例来演示怎样 ...

  7. 关于ajax技术

    传统注册存在的弊端 : 当我们点击注册时,会存在以下几个问题. 首先,浏览器会销毁当前页面,如果注册失败返回的新页面所有之前 填写的数据丢失. 其次,如果网络通信较差,我们表单提交请求数据到服务端,而 ...

  8. (Go)07.Go语言中strings和strconv包示例代码详解02

    1.strings使用 统计字符串出现次数 strings.Count(s string, substr string) int Count 用于计算字符串 substr 在字符串 s 中出现的非重叠 ...

  9. 日期数据类型为Date ,前台传递喂String的后台处理

    方法一: 在实体类里面将set方法里面将数据类型转为Date public void setBirth(String birth) { SimpleDateFormat sdf = new Simpl ...

  10. mysql数据库的介绍及安装

    一.什么是数据库 1.什么是数据(Data) 描述事物的符号记录成为数据,描述事物的符号既可以是文字.图片.图像.声音.语言等,数据有多种表现形式,他们都可以经过数字化后存入计算机 在计算机中描述一个 ...