#include <bits/stdc++.h>
using namespace std;
int zzp;//zzp ak ioi %%%
int cnt=0;
int root=0;
struct tree{
int lc,rc;
int amo,siz;
int pri,val;
}tr[100001];
void pushup(int p){
tr[p].siz=tr[tr[p].lc].siz+tr[tr[p].rc].siz+tr[p].amo;
}
void zig(int &p){//右旋
int q=tr[p].lc;
tr[p].lc=tr[q].rc;
tr[q].rc=p;
pushup(p);
p=q;
}
void zag(int &p){//左旋
int q=tr[p].rc;
tr[p].rc=tr[q].lc;
tr[q].lc=p;
pushup(p);
p=q;
}/*
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
ssssss
插入 xx 数
删除 xx 数(若有多个相同的数,因只删除一个)
查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 )
查询排名为 xx 的数
求 xx 的前驱(前驱定义为小于 xx,且最大的数)
求 xx 的后继(后继定义为大于 xx,且最小的数)
*/
int node(int val){
tr[++cnt].val=val;
tr[cnt].pri=rand();
tr[cnt].rc=tr[cnt].lc=0;
tr[cnt].amo=1;
tr[cnt].siz=1;
return cnt;
}
void insert(int &p,int val){
if (!p){
p=node(val);
return ;
}
if (val==tr[p].val) {
tr[p].amo++;
}
if (val<tr[p].val){
insert(tr[p].lc,val);
if (tr[p].pri<tr[tr[p].lc].pri) zig(p);
}
if (val>tr[p].val){
insert(tr[p].rc,val);
if (tr[p].pri<tr[tr[p].rc].pri) zag(p);
}
pushup(p);
}
void dele(int &p,int val){
if (!p) return ;
tr[p].siz--;
if (val==tr[p].val){
if (tr[p].amo>1) tr[p].amo--;
else {
if (!tr[p].lc||!tr[p].lc){
p=tr[p].lc+tr[p].rc;
} else if (tr[tr[p].lc].pri>tr[tr[p].rc].pri){
zig(p);
dele(tr[p].rc,val);
return ;
} else {
zag(p);
dele(tr[p].lc,val);
return ;
}
}
}
if (val<tr[p].val){
dele(tr[p].lc,val);
} else {
dele(tr[p].rc,val);
}
pushup(p);
}
/*
void erase(int &now,int data)
{
t[now].siz--;
if(t[now].data==data)
{
if(t[now].left==0&&t[now].right==0)
{
now=0;
return ;
}
if(t[now].left==0||t[now].right==0)
{
now=t[now].left+t[now].right;
return ;
}
if(t[t[now].left].value<t[t[now].right].value)
{
right_rorate(now);
erase(t[now].right,data);
return ;
}
else
{
left_rorate(now);
erase(t[now].left,data);
return ;
}
}
if(t[now].data>=data)
{
erase(t[now].left,data);
}
else
{
erase(t[now].right,data);
}
up(now);
}
*/
int rank1(int p,int val){
if (!p) return 0;
if (tr[p].val==val){
return tr[tr[p].lc].siz+1;
}
if (tr[p].val<val)
return rank1(tr[p].lc,val);
else{
return rank1(tr[p].rc,val)+tr[tr[p].lc].siz+tr[p].amo;
}
}
int derank(int p,int val){
if (!p) return 0;
if (tr[tr[p].lc].siz>val) return derank(tr[p].lc,val);
if (tr[tr[p].lc].siz+tr[p].amo>=val)
return tr[p].val;
return derank(tr[p].rc,val-tr[tr[p].lc].siz-tr[p].amo);
}
int pre(int val){
int p=root;
int res=0;
while(p){
if (tr[p].val<val){
res=tr[p].val;
p=tr[p].rc;
}
else
p=tr[p].lc;
}
return res;
}
int next(int val){
int p=root;
int res=0;
while (p){
if (tr[p].val>val){
res=tr[p].val;
p=tr[p].lc;
}
else
p=tr[p].rc;
}
return res;
}
int main()
{
srand(time(NULL));
cin>>zzp;
for (int i=1;i<=zzp;i++){
int opt,x;
cin>>opt>>x;
if (opt==1) insert(root,x);
if (opt==2) dele(root,x);
if (opt==3) cout<<rank1(root,x)<<endl;
if (opt==4) cout<<derank(root,x)<<endl;
if (opt==5) cout<<pre(x)<<endl;
if (opt==6) cout<<next(x)<<endl;
}
return 0;
} //insert&&rank
题目通道