解题关键:无旋treap模板。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define maxn 500001
using namespace std;
typedef long long ll;
int size[maxn],ch[maxn][],rnd[maxn],val[maxn];
int ncnt,n,x,y,z,rt; inline void pushup(int x){
size[x]=+size[ch[x][]]+size[ch[x][]];
} inline int new_node(int x){
size[++ncnt]=;
val[ncnt]=x;
rnd[ncnt]=rand();
return ncnt;
}
//核心
int merge(int A,int B){
if(!A||!B) return A+B;
if(rnd[A]<rnd[B]){ch[A][]=merge(ch[A][],B);
pushup(A);return A;}
else {ch[B][]=merge(A,ch[B][]);
pushup(B);return B;}
}
//权值分裂
void split(int now,int k,int &x,int &y){
if(!now) x=y=;
else{
if(val[now]<=k) x=now,split(ch[now][],k,ch[now][],y);
else y=now,split(ch[now][],k,x,ch[now][]);
pushup(now);
}
}
//排名分裂
void split_2(int now,int k,int &x,int &y){
if(!now) x=y=;
else{
if(k<=size[ch[now][]]){y=now;split(ch[now][],k,x,ch[now][]);}
else{x=now;split(ch[now][],k-size[ch[now][]]-,ch[now][],y);}
pushup(now);
}
} void insert(int &k,int a){
split(k,a,x,y);
k=merge(merge(x,new_node(a)),y);
}
//会浪费空间,没有回收节点
void del(int &k,int a){
split(k,a,x,z);
split(x,a-,x,y);
y=merge(ch[y][],ch[y][]);
k=merge(merge(x,y),z);
} int rnk(int &k,int a){
split(k,a-,x,y);
int res=size[x]+;
k=merge(x,y);
return res;
} int kth(int now,int k){
while(){
if(k<=size[ch[now][]]) now=ch[now][];
else if(k==size[ch[now][]]+) return val[now];
else k-=size[ch[now][]]+,now=ch[now][];
}
} int pred(int &k,int a){
split(k,a-,x,y);
int res=kth(x,size[x]);
k=merge(x,y);
return res;
} int succ(int &k,int a){
split(k,a,x,y);
int res=kth(y,);
k=merge(x,y);
return res;
} int main(){
srand(time());
scanf("%d",&n);
for(int i=,opt,a;i<=n;i++){
scanf("%d%d",&opt,&a);
switch(opt){
case :insert(rt,a);break;
case :del(rt,a);break;
case :printf("%d\n",rnk(rt,a));break;
case :printf("%d\n",kth(rt,a));break;
case :printf("%d\n",pred(rt,a));break;
case :printf("%d\n",succ(rt,a));break;
}
}
return ;
}
05-11 18:14