#include "bits/stdc++.h"
using namespace std;
#define MAXN 100010
struct Treap{
int LeftSon,RightSon;
int Count,Size;
int Pos,Val;
}Tree[MAXN];
inline void UpData(int Root){
int L=Tree[Tree[Root].LeftSon].Size;
int R=Tree[Tree[Root].RightSon].Size;
Tree[Root].Size=L+R+Tree[Root].Count;
return;
}
inline void TurnRight(int &Root){
int L=Tree[Root].LeftSon;
Tree[Root].LeftSon=Tree[L].RightSon;
Tree[L].RightSon=Root;
Tree[L].Size=Tree[Root].Size;
UpData(Root),Root=L;
return;
}
inline void TurnLeft(int &Root){
int R=Tree[Root].RightSon;
Tree[Root].RightSon=Tree[R].LeftSon;
Tree[R].LeftSon=Root;
Tree[R].Size=Tree[Root].Size;
UpData(Root),Root=R;
return;
}
int Top;
inline void InPut(int Val,int &Root){
if(Tree[Root].Val==0){
Root=(++Top);
Tree[Root].LeftSon=Tree[Root].RightSon=0;
Tree[Root].Size=Tree[Root].Count=1;
Tree[Root].Pos=rand()%100000007;
Tree[Root].Val=Val;
return;
}
Tree[Root].Size++;
if(Val==Tree[Root].Val){
Tree[Root].Count++;
return;
}
if(Val<Tree[Root].Val){
InPut(Val,Tree[Root].LeftSon);
int L=Tree[Root].LeftSon;
if(Tree[L].Pos<Tree[Root].Pos)
TurnRight(Root);
return;
}
if(Val>Tree[Root].Val){
InPut(Val,Tree[Root].RightSon);
int R=Tree[Root].RightSon;
if(Tree[R].Pos<Tree[Root].Pos)
TurnLeft(Root);
return;
}
return;
}
inline int LeftMax(int Root){
Root=Tree[Root].LeftSon;
while(Tree[Root].RightSon!=0)
Root=Tree[Root].RightSon;
return Root;
}
inline int RightMin(int Root){
Root=Tree[Root].RightSon;
while(Tree[Root].LeftSon!=0)
Root=Tree[Root].LeftSon;
return Root;
}
inline void Del(int Val,int &Root){
if(Root==0)return;
Tree[Root].Size--;
if(Tree[Root].Val==Val){
if(Tree[Root].Count>1){
Tree[Root].Count--;
return;
}
int New;
if(Tree[Root].LeftSon>0){
New=LeftMax(Root);
Tree[Root].Count=Tree[New].Count;
Tree[Root].Val=Tree[New].Val;
Del(Tree[New].Val,New);
return;
}
if(Tree[Root].RightSon>0){
New=RightMin(Root);
Tree[Root].Count=Tree[New].Count;
Tree[Root].Val=Tree[New].Val;
Del(Tree[New].Val,New);
return;
}
Tree[Root].Size=Tree[Root].Count=0;
Tree[Root].Val=Tree[Root].Pos=0;
Root=0;
return;
}
if(Tree[Root].Val>Val)
Del(Val,Tree[Root].LeftSon);
if(Tree[Root].Val<Val)
Del(Val,Tree[Root].RightSon);
return;
}
inline int SearchRank(int Root,int Val){
int L=Tree[Root].LeftSon;
int R=Tree[Root].RightSon;
int Now=Tree[Root].Count;
if(Tree[Root].Val>Val)
return SearchRank(L,Val);
if(Tree[Root].Val==Val)
return Tree[L].Size+1;
if(Tree[Root].Val<Val)
return Tree[L].Size+Now+SearchRank(R,Val);
}
inline int SearchNum(int Root,int Rank){
int L=Tree[Root].LeftSon;
int R=Tree[Root].RightSon;
if(Tree[L].Size>=Rank&&L!=0)
return SearchNum(L,Rank);
if(Tree[L].Size+Tree[Root].Count>=Rank)
return Tree[Root].Val;
int J=Tree[L].Size+Tree[Root].Count;
if(R!=0)return SearchNum(R,Rank-J);
}
#define INF 1<<30
inline int Pre(int Root,int Val){
int Max=-INF;
if(Root==0)
return -INF;
int L=Tree[Root].LeftSon;
int R=Tree[Root].RightSon;
if(Tree[Root].Val<Val){
Max=max(Max,Tree[Root].Val);
Max=max(Max,Pre(R,Val));
}
if(Tree[Root].Val>=Val)
Max=max(Max,Pre(L,Val));
return Max;
}
inline int Next(int Root,int Val){
int Min=INF;
if(Root==0)
return INF;
int L=Tree[Root].LeftSon;
int R=Tree[Root].RightSon;
if(Tree[Root].Val>Val){
Min=min(Min,Tree[Root].Val);
Min=min(Min,Next(L,Val));
}
if(Tree[Root].Val<=Val)
Min=min(Min,Next(R,Val));
return Min;
}
inline int Read(void){
int X=0,Y=1;char C=getchar();
while(C>'9'||C<'0'){if(C=='-'){Y=-1;}C=getchar();}
while('0'<=C&&C<='9'){X=X*10+(C-'0');C=getchar();}
return (X*Y);
}
int N,X,Y,Root;
int main(void){
N=Read();
for(register int i=1;i<=N;i++){
X=Read(),Y=Read();
switch(X){
case 1:{
InPut(Y,Root);
break;
}
case 2:{
Del(Y,Root);
break;
}
case 3:{
printf("%d\n",SearchRank(Root,Y));
break;
}
case 4:{
printf("%d\n",SearchNum(Root,Y));
break;
}
case 5:{
printf("%d\n",Pre(Root,Y));
break;
}
case 6:{
printf("%d\n",Next(Root,Y));
break;
}
}
}
return 0;
}
/*
8
1 577793
1 408221
1 880861
2 408221
1 460353
1 223489
6 577713
4 2
*/
测评记录