传送门
附上两篇讲解:
http://www.cnblogs.com/nietzsche-oier/p/6748292.html
http://blog.youkuaiyun.com/zmh964685331/article/details/50536410
P.S.非旋转treap比普通treap慢,比splay快,可以实现splay能实现的而其余平衡树无法实现的操作比如区间翻转。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define mp(x,y) make_pair(x,y)
const int MAXN=1e5+4;
typedef pair<int ,int > pii;
struct Node {
int lc,rc,val,key,siz;
}t[MAXN];
int n,x,root,cnt,opt;
inline void update(int rt) {
t[rt].siz=t[t[rt].lc].siz+t[t[rt].rc].siz+1;
}
pii split(int a,int n) {
if (!n) return mp(0,a);
int lc(t[a].lc),rc(t[a].rc);
if (n==t[lc].siz) return t[a].lc=0,update(a),mp(lc,a);
if (n==t[lc].siz+1) return t[a].rc=0,update(a),mp(a,rc);
if (n<t[lc].siz) {
pii tmp=split(lc,n);
t[a].lc=tmp.second,update(a);
return mp(tmp.first,a);
}
pii tmp=split(rc,n-t[lc].siz-1);
t[a].rc=tmp.first,update(a);
return mp(a,tmp.second);
}
int merge(int a,int b) {
if (!a||!b) return a+b;
if (t[a].key<t[b].key) return t[a].rc=merge(t[a].rc,b),update(a),a;
else return t[b].lc=merge(a,t[b].lc),update(b),b;
}
int rank(int x,int rt) {//数x的排名
int ret=0,tmp=1e9;
while (rt) {
if (x==t[rt].val) tmp=min(tmp,ret+t[t[rt].lc].siz+1);
if (x>t[rt].val) ret+=t[t[rt].lc].siz+1,rt=t[rt].rc;
else rt=t[rt].lc;
}
return tmp==(int)1e9?ret:tmp;
}
int find(int x,int rt) {
while (true) {
if (t[t[rt].lc].siz==x-1) return t[rt].val;
if (t[t[rt].lc].siz>x-1) rt=t[rt].lc;
else x-=t[t[rt].lc].siz+1,rt=t[rt].rc;
}
}
int pre(int x,int rt) {
int ret=-1e9;
while (rt) {
if (x>t[rt].val) ret=max(ret,t[rt].val),rt=t[rt].rc;
else rt=t[rt].lc;
}
return ret;
}
int nxt(int x,int rt) {
int ret=1e9;
while (rt) {
if (x<t[rt].val) ret=min(ret,t[rt].val),rt=t[rt].lc;
else rt=t[rt].rc;
}
return ret;
}
inline void Insert(int x) {
int k=rank(x,root);
pii tmp=split(root,k);
t[++cnt].val=x;
t[cnt].key=rand();
t[cnt].siz=1;
root=merge(tmp.first,cnt);
root=merge(root,tmp.second);
}
inline void del(int x){
int k=rank(x,root);
pii t1=split(root,k);
pii t2=split(t1.first,k-1);
root=merge(t2.first,t1.second);
}
int main() {
// freopen("bzoj 3224.in","r",stdin);
scanf("%d",&n);
for (register int i=0;i<n;++i) {
scanf("%d%d",&opt,&x);
switch (opt) {
case 1:Insert(x);break;
case 2:del(x);break;
case 3:printf("%d\n",rank(x,root));break;
case 4:printf("%d\n",find(x,root));break;
case 5:printf("%d\n",pre(x,root));break;
case 6:printf("%d\n",nxt(x,root));break;
}
}
return 0;
}