2,373
社区成员




#include<bits/stdc++.h>
#define f(i,a,b) for(int i = a ; i<=b ; i++)
using namespace std;
const int N = 1e5+5;
int n,rt,op,x;
struct treap{
int ls,rs;//左孩子,右孩子
int key;//当前点的值
int siz,pri;//子树大小,优先级
}t[N];
int cnt;//总结点个数
void newnode(int x){//创建新节点。
++cnt;
t[cnt].ls = t[cnt].rs = 0;
t[cnt].key = x;
t[cnt].siz = 1;
t[cnt].pri = rand();
return ;
}
#define l t[u].ls
#define r t[u].rs
void update(int u){
t[u].siz = t[l].siz+t[r].siz+1;//合并siz数组
return ;
}
void rotate(int &u,int d){
int k;
if(!d){
k = r;
r = t[k].ls;
t[k].ls = u;
}else{
k = l;
l = t[k].rs;
t[k].rs = u;
}
t[k].siz+=t[u].siz;//更新
update(u);//合并siz
u = k;//更新u
return ;
}
void insert(int &u,int x){//插入一个节点
if(!u){//如果当前节点为空...
newnode(x);//新建节点。
u = cnt;//设置u。
return;
}
t[u].siz++;//设置当前子树大小自增。
if(t[u].key<=x){//如果当前节点的键值小于要插入的值...
insert(r,x);//递归插入。
if(t[u].pri<t[r].pri) rotate(u,0);//如果权值不满足要求,旋转。
}
else{//另一侧...
insert(l,x);//递归。
if(t[u].pri<t[l].pri) rotate(u,1);//旋转。
}
update(u);
return;
}
void del(int &u,int x){//删除元素...
--t[u].siz;//siz自减。
if(t[u].key==x){//如果删除的就是当前节点...
if(!l&&!r){//如果当前节点是叶子...
u = 0;//删除。
return;
}
if(!l||!r){//如果只有一个子树...
u = l+r;
return;
}
if(t[l].pri<t[r].pri){//左儿子和右儿子权值...
rotate(u,1);//旋转。
del(r,x);//递归。
return;
}
else{
rotate(u,0);
del(l,x);
return;
}
}
if(t[u].key<x) del(r,x);
else del(l,x);
update(u);
}
int rank1(int u,int x){
if(!u) return 0;
if(x>t[u].key) return t[l].siz+rank1(r,x)+1;
return rank1(l,x);
}
int kth(int u,int k){
if(t[l].siz == k-1) return t[u].key;
else if(t[l].siz<k-1) return kth(r,k-t[l].siz-1);
else return kth(l,k);
}
int pre(int u,int x){
if(!u) return 0;
if(t[u].key>=x) return pre(l,x);
int tmp = pre(r,x);
if(!tmp) return t[u].key;
return tmp;
}
int post(int u,int x){
if(!u) return 0;
if(t[u].key<=x) return post(r,x);
int tmp = post(l,x);
if(!tmp) return t[u].key;
return tmp;
}
int main(){
srand(time(0));
cin>>n;
f(i,1,n){
cin>>op>>x;
if(op == 1) insert(rt,x);
if(op == 2) del(rt,x);
if(op == 3) cout<<rank1(rt,x)+1<<endl;
if(op == 4) cout<<kth(rt,x)<<endl;
if(op == 5) cout<<pre(rt,x)<<endl;
if(op == 6) cout<<post(rt,x)<<endl;
}
return 0;
}