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 国的 ...
随机推荐
- pg 学习资料
文/谭峰 DBA,PostgreSQL专家 开源数据库 PostgreSQL 中文资料非常缺乏,很多社区朋友苦于上手的中文资料少,因此汇总收集以下 PostgreSQL 中文资料,包括 Postgre ...
- JS 缓冲运动 带运动的留言本 小案例
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- Hard模式题目
先过一下Hard模式的题目吧. # Title Editorial Acceptance Difficulty Frequency . 65 Valid Number 12.6% Ha ...
- ubuntu上java的开发环境 jdk 的安装
jre下载路径: https://java.com/zh_CN/download/manual.jsp jdk下载路径:http://www.oracle.com/technetwork/java/j ...
- Pig 在 shell script中被调用,批量载入处理文件
首先,我想达到的目的是批量的处理一个目录下的的很多文档,这些文档保存了我要处理的数据,由于pig是初学..所以不知到该怎么批量的load,没有写过 自己的UDF,仅仅能一个一个文件的load,然后处理 ...
- Android面试常问的技术问题
面试时技术经理会问你一些工作中遇到的Android方面的问题.谈谈你所做的项目,和在项目中所扮演的角色. 很多其它内容请參考我的博客:点击打开链接 1.怎样优化ListView? ①Item布局,层级 ...
- iOS社会化分享(干货)
一.苹果原生集成的社会化分享 1.哪些平台 (1)Twitter (2)FaceBook (3)Flickr (4)Vimeo (5)新浪微博 :iOS6 (6)腾讯微博 : iOS7 2.框架 : ...
- Jmeter - 服务器性能检测
在对系统做压力测试时,往往需要对服务的性能进行监控,包括CPU,Memory,IO,还有网络情况进行监控. Jemter有个一插件,能很好的支持这些性能监控.原理是服务器启动服务之后,测试机发起请求, ...
- HTTPS 为什么更安全,先看这些
HTTPS 是建立在密码学基础之上的一种安全通信协议,严格来说是基于 HTTP 协议和 SSL/TLS 的组合.理解 HTTPS 之前有必要弄清楚一些密码学的相关基础概念,比如:明文.密文.密码.密钥 ...
- 大白话理解cookie
HTTP协议是一个无状态的协议,服务器无法区分出两次请求是否发送自同一服务器. 需要通过会话控制来解决这个问题,会话控制主要有两种方式Cookie 和 Session. Cookie就是一个头,Coo ...