传送门
SOL
非旋treap (fhp_treap)板子
(同普通平衡树)
CODE
#include<bits/stdc++.h>
using namespace std;
#define sf scanf
#define pf printf
#define fi first
#define se second
const int maxn=3e5+10;
typedef pair<int,int> T;
int n,pri[maxn],val[maxn],ch[maxn][2],siz[maxn],rt,tot=0;
inline void pushup(int p){siz[p]=siz[ch[p][0]]+siz[ch[p][1]]+1;}
inline int creat(int k){val[++tot]=k;pri[tot]=rand();siz[tot]=1;return tot;}
//megre的前提:两个区间是连续的并且不重叠
inline int merge(int x,int y){
if(!x||!y)return x+y;
if(pri[x]>pri[y]){
ch[x][1]=merge(ch[x][1],y);
pushup(x);
return x;
}
else{
ch[y][0]=merge(x,ch[y][0]);
pushup(y);
return y;
}
}
inline T split(int p,int k){
if(!p)return make_pair(0,0);
T res,tmp;
if(siz[ch[p][0]]>=k){
//当前节点在右边的那一部分
tmp=split(ch[p][0],k);
ch[p][0]=tmp.se;
res.fi=tmp.fi;res.se=p;
pushup(p);
}
else{
//当前节点在左边的那一部分
tmp=split(ch[p][1],k-(siz[ch[p][0]]+1));
ch[p][1]=tmp.fi;
res.fi=p;res.se=tmp.se;
pushup(p);
}
return res;
}
inline int rank(int p,int k){
if(!p)return 1;
if(val[p]<k)return siz[ch[p][0]]+1+rank(ch[p][1],k);
else return rank(ch[p][0],k);
}
inline int kth(int p,int k){
if(!p)return -1;
if(siz[ch[p][0]]+1==k)return val[p];
if(siz[ch[p][0]]>=k) return kth(ch[p][0],k);
else return kth(ch[p][1],k-(siz[ch[p][0]]+1));
}
inline void add(int vl){
int p=creat(vl),k=rank(rt,vl)-1;
T t=split(rt,k);
rt=merge(merge(t.fi,p),t.se);
}
inline void delt(int vl){
int k=rank(rt,vl);
T t=split(rt,k);
rt=merge(split(t.fi,k-1).fi,t.se);
}
inline int pre(int vl){return kth(rt,rank(rt,vl)-1);}
inline int nxt(int vl){return kth(rt,rank(rt,vl+1));}
signed main(){
srand(time(0));
sf("%d",&n);
while(n--){
int f,x;sf("%d%d",&f,&x);
if(f==0)add(x);
if(f==1)delt(x);
if(f==2)pf("%d\n",kth(rt,x));
if(f==3)pf("%d\n",rank(rt,x)-1);
if(f==4)pf("%d\n",pre(x));
if(f==5)pf("%d\n",nxt(x));
}
return 0;
}