Treap
#include <iostream>
#include<cstdio>
#include <queue>
#include <stack>
using namespace std;
const int maxn=1e5+50;
int fa[maxn];
int ch[maxn][2];
int dat[maxn];
int sz[maxn];
int rep[maxn];
int val[maxn];
stack<int> ava;
#define left(i) (ch[i][0])
#define right(i) (ch[i][1])
#define sons(i,j) (ch[i][j])
#define lorr(i,j) (dat[i]>dat[j])
void destroy_node(int i,int f)
{
fa[i]=ch[i][0]=ch[i][1]=rep[i]=sz[i]=0;
ava.push(i);
}
int seed=1234;
const int maxx=0x3f3f3f3f<<1;
int rand()
{
return int(seed=seed*123456LL%maxx);
}
int ff=0;
int new_node(int data,int f)
{
int n=ava.top();
ava.pop();
fa[n]=f;
rep[n]=sz[n]=1;
val[n]=rand();
dat[n]=data;
sons(f,lorr(n,f))=n;
return n ;
}
int init_ava()
{
for(int i=maxn-1; i; i--)
ava.push(i);
}
int root=0;
void updata(int i)
{
sz[i]=sz[left(i)]+sz[right(i)]+rep[i];
}
void brotate(int i)
{
if(!i)return ;
int f=fa[i],ff=fa[f];
sons(ff,lorr(f,ff))=0;
sons(ff,lorr(i,ff))=i;
fa[i]=ff;
fa[f]=i;
sons(f,lorr(i,f))=sons(i,!lorr(i,f));
fa[sons(i,!lorr(i,f))]=f;
sons(i,!lorr(i,f))=f;
if(!fa[i])root=i;
updata(f);
updata(i);
// show(9);
}
int f=0;
void inserts(int data,int index)
{
if(!index)
{
int t=new_node(data,f);
if(!root)root=t;
return ;
}
else if(dat[index]==data) {
rep[index]++;
sz[index]++;
return ;
}
else {
f=index;
if(data>dat[index]) {
inserts(data,right(index));
}
else inserts(data,left(index));
sz[index]++;
}
index=sons(index,data>dat[index]);
if(fa[index]&&val[index]>val[fa[index]])
{
brotate(index);
}
}
int ends1,rep1;
void clears(){ends1=f=0;rep1=1;}
void dels(int data,int &index)
{
if(dat[index]==data&&rep[index]>1){
rep[index]--;
sz[index]--;
return ;
}
if(dat[index]==data||right(index)==0&&data>dat[index]||left(index)==0&&data<dat[index])
{
if(right(index)==0||left(index)==0){
int sf=right(index)+left(index);
ends1=dat[index];
rep1=rep[index];
fa[sf]=fa[index];
int t=index;
destroy_node(index,fa[index]);
index=sf;
}
else
{
dels(data+1,left(index));
dat[index]=ends1;
sz[index]-=1;
rep[index]=rep1;
rep1=1;
}
return ;
}
dels(data,sons(index,data>dat[index]));
sz[index]-=rep1;
}
int get_rank(int data,int index) {
if(dat[index]==data) {
return sz[left(index)]+1;
}
int c=(data>dat[index])?1:0;
int d=c?sz[left(index)]+rep[index]:0;
return d+get_rank(data,sons(index,c));
}
int get_item(int locat,int index) {
if(locat>sz[left(index)]&&locat<=sz[left(index)]+rep[index])
return dat[index];
int d=locat>sz[left(index)]+rep[index];
return get_item(d?locat-rep[index]-sz[left(index)]:locat,sons(index,d));
}
inline int get_prev(int data,int index,int ans)
{
if(!index)
return ans;
int d=data>dat[index];
return get_prev(data,sons(index,d),d?dat[index]:ans);
}
inline int get_lat(int data,int index,int ans)
{
if(!index)
return ans;
int d=data<dat[index];
return get_lat(data,sons(index,!d),d?dat[index]:ans);
}
int y=0;
int choice(int ch,int dat)
{
clears();
ch--;
switch(ch)
{
case 0:
inserts(dat,root);
break;
case 1:
dels(dat,root);
break;
case 2:
printf("%d\n",get_rank(dat,root));
break;
case 3:
printf("%d\n",get_item(dat,root));
break;
case 4:
printf("%d\n",get_prev(dat,root,-maxx));
break;
case 5:
printf("%d\n",get_lat(dat,root,maxx));;
break;
}
}
int main()
{
init_ava();
int n;
scanf("%d",&n);
while(n--)
{
int x,y;
scanf("%d %d",&x,&y);
choice(x,y);
}
return 0;
}