Splay 均摊复杂度证明见此处 \(\rightarrow\) 链接

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int inf=0x3f3f3f3f; struct node{
#define ls(x) t[x].ch[0]
#define rs(x) t[x].ch[1]
int fa,ch[2],val,size,cnt;
}t[maxn];
int tot,root;
inline int get(int x){return x==rs(t[x].fa);}
inline void pushup(int x){
t[x].size=t[ls(x)].size+t[rs(x)].size+t[x].cnt;
}
inline int find(int val){
int x=root;
while(t[x].val!=val&&t[x].ch[t[x].val<val])x=t[x].ch[t[x].val<val];
return x;
}
inline void rotate(int x){
int fa=t[x].fa,gfa=t[fa].fa;
int d1=get(x),d2=get(fa);
t[fa].ch[d1]=t[x].ch[d1^1],t[t[x].ch[d1^1]].fa=fa;
t[x].ch[d1^1]=fa,t[fa].fa=x;
t[x].fa=gfa,t[gfa].ch[d2]=x;
pushup(fa),pushup(x);
}
inline void splay(int x,int goal){
while(t[x].fa!=goal){
int fa=t[x].fa,gfa=t[fa].fa;
if(gfa!=goal)get(x)==get(fa)?rotate(fa):rotate(x);
rotate(x);
}
if(!goal)root=x;
}
void insert(int val){
int x=root,fa=0;
while(x&&t[x].val!=val)fa=x,x=t[x].ch[t[x].val<val];
if(x)++t[x].cnt;
else{
x=++tot;
if(fa)t[fa].ch[t[fa].val<val]=x;
t[x].fa=fa,t[x].val=val,t[x].cnt=t[x].size=1;
}
splay(x,0);
}
int kth(int x,int k){
if(k<=t[ls(x)].size)return kth(ls(x),k);
else if(k>t[ls(x)].size+t[x].cnt)return kth(rs(x),k-t[ls(x)].size-t[x].cnt);
else return t[x].val;
}
int getrank(int val){
splay(find(val),0);
return t[ls(root)].size;
}
int getpre(int val){
splay(find(val),0);
if(t[root].val<val)return root;
int x=ls(root);
while(rs(x))x=rs(x);
return x;
}
int getnxt(int val){
splay(find(val),0);
if(t[root].val>val)return root;
int x=rs(root);
while(ls(x))x=ls(x);
return x;
}
void remove(int val){
int pre=getpre(val),nxt=getnxt(val);
splay(pre,0),splay(nxt,pre);
if(t[ls(nxt)].cnt>1)--t[ls(nxt)].cnt,splay(ls(nxt),0);
else ls(nxt)=0,splay(nxt,0);
}
void initial(){insert(-inf),insert(inf);} int main(){
initial();
int opt,val,n;
scanf("%d",&n);
while(n--){
scanf("%d%d",&opt,&val);
switch(opt){
case 1:insert(val);break;
case 2:remove(val);break;
case 3:printf("%d\n",getrank(val));break;
case 4:printf("%d\n",kth(root,val+1));break;
case 5:printf("%d\n",t[getpre(val)].val);break;
case 6:printf("%d\n",t[getnxt(val)].val);break;
}
}
return 0;
}

【模板】Splay的更多相关文章

  1. 算法模板——splay区间反转 2

    实现功能:同splay区间反转 1(基于BZOJ3223 文艺平衡树) 这次改用了一个全新的模板(HansBug:琢磨了我大半天啊有木有),大大简化了程序,同时对于splay的功能也有所完善 这里面没 ...

  2. 算法模板——splay区间反转 1

    实现的功能:将序列区间反转,并维护 详见BZOJ3223 var i,j,k,l,m,n,head,a1,a2:longint; s1:ansistring; a,b,c,d,fat,lef,rig: ...

  3. 【luogu P3369 普通平衡树(Treap/SBT)】 模板 Splay

    题目链接:https://www.luogu.org/problemnew/show/P3369 #include <cstdio> #include <algorithm> ...

  4. 洛谷 P3391 模板Splay

    #include<bits/stdc++.h> using namespace std; #define maxn 200000 int read() { ,w=; ;ch=getchar ...

  5. [模板] Splay

    欠了好久的Splay,以后就它了. 默写真不容易,过几天估计就忘了.. 整个Splay真的精妙,不拖泥带水那种.. 前驱后继之所以不能用rk转到根,是因为这个数不一定存在.. kth中<=老忘记 ...

  6. 模板—splay

    #include<iostream> #include<cstdio> #define cin(x) scanf("%d",&x) using na ...

  7. 模板——Splay

    $Splay$ #include <bits/stdc++.h> #define inf (int)1e9 using namespace std; const int N=1e5+100 ...

  8. Splay 伸展树

    废话不说,有篇论文可供参考:杨思雨:<伸展树的基本操作与应用> Splay的好处可以快速分裂和合并. ===============================14.07.26更新== ...

  9. [NOI2003][bzoj1507] 文本编辑器 editor [splay]

    其实看明白了就是一道水题 毕竟模板 splay敲一发,插入一个串的时候先把它构建成一棵平衡树,再挂到原来的splay上面去即可 没别的了,上代码 #include<iostream> #i ...

  10. splay最终模板

    来自wjmzbmr的splay模板 #include<cstdio> #include<iostream> #include<algorithm> using na ...

随机推荐

  1. 基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-5

    来个目录吧: 第一章-入门 第二章- Entity Framework Core Nuget包管理 第三章-创建.修改.删除.查询 第四章-排序.过滤.分页.分组 第五章-迁移,EF Core 的co ...

  2. C#大型电商项目优化(三)——扩展性与支付

    上一篇文章引来不少非议,笔者并非对EF有看法,而是针对不同的业务场景和框架背景,挑选不同的方案.每个方案都有其优势劣势,挑选最快速,最简单的方案,是笔者的初衷. 看评论也是学习的过程,然而有些只做评价 ...

  3. LVS负载均衡-基础知识梳理

    一. 集群的概念 服务器集群简称集群是一种服务器系统,它通过一组松散集成的服务器软件和/或硬件连接起来高度紧密地协作完成计算工作.在某种意义上,他们可以被看作是一台服务器.集群系统中的单个服务器通常称 ...

  4. php 多个文件压缩到一起存储

    $zip = new ZipArchive();$res = $zip->open('test.zip', ZipArchive::CREATE); //不存在则创建$filepath = 's ...

  5. Finished yeah!

    终于到了最后的博客阶段,这时候才知道博客此时此刻是多么的惬意,它成了书写心声的自由平台!耗时一天完成这作业说起来也是蛮辛苦的,编译器需要新装,IDE需要熟悉,当然最主要的是之前浅入浅出的C++功底在此 ...

  6. VIM编辑器常用命令(转)

    转自:https://www.cnblogs.com/Nice-Boy/p/6124177.html

  7. UML类图及类与类之间的关系

    原文地址:http://www.uml.org.cn/oobject/201211231.asp 类图用于描述系统中所包含的类以及它们之间的相互关系,帮助人们简化对系统的理解,它是系统分析和设计阶段的 ...

  8. 手工编程:hello world

    全部用命令行工具和Notepad编辑器,用手工创建并编译一个C的命令行程序:hello world. public class Hello{         public static void ma ...

  9. Quartz中时间表达式的设置-----corn表达式 (转)(http://www.cnblogs.com/GarfieldTom/p/3746290.html)

    Quartz中时间表达式的设置-----corn表达式 (注:这是让我看比较明白的一个博文,但是抱歉,没有找到原作者,如有侵犯,请告知) 时间格式: <!-- s m h d m w(?) y( ...

  10. Glace:generator-jhipster, adding User entity enhancement management

    https://github.com/jhipster/generator-jhipster/issues/2538 jhipster,很好用的开发工具.国外知名度高,国内未普及,国外大公司在用. j ...