解析:http://www.cnblogs.com/zwfymqz/p/7898210.html
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct one
{
int v,fa,ch[2],rec,sum;
};
one tree[500000];
int n,tot=0,pointnum=0;
#define root tree[0].ch[1]
int iden(int x)
{
return tree[tree[x].fa].ch[0]==x?0:1;
}
inline void connect(int x,int fa,int how)
{
tree[x].fa=fa;
tree[fa].ch[how]=x;
}
inline void update(int x)
{
tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec;}
inline void rotate(int x)
{
int Y=tree[x].fa;
int R=tree[Y].fa;
int Yson=iden(x);
int Rson=iden(Y);
int B=tree[x].ch[Yson^1];
connect(x,R,Rson);
connect(Y,x,Yson^1);
connect(B,Y,Yson);
update(Y);update(x);
}
void splay(int x,int to)
{
to=tree[to].fa;
while(tree[x].fa!=to)
{
if(tree[tree[x].fa].fa==to)rotate(x);
else if(iden(x)==iden(tree[x].fa))rotate(tree[x].fa),rotate(x);
else rotate(x),rotate(x);
}
}
void newpoint(int v,int fa)
{
tree[++tot].v=v;
tree[tot].fa=fa;
tree[tot].sum=tree[tot].rec=1;
}
int build(int v)
{
pointnum++;
if(tot==0){root=1;newpoint(v,0);}
else
{
int now=root;
while(1)
{
tree[now].sum++;
if(tree[now].v==v){tree[now].rec++;return now;}
int nxt=v<tree[now].v?0:1;
if(!tree[now].ch[nxt])
{
newpoint(v,now);tree[now].ch[nxt]=tot;return tot;
}
now=tree[now].ch[nxt];
}
}
return 0;
}
inline void dele(int x)
{
tree[x].v=tree[x].fa=tree[x].ch[0]=tree[x].rec=tree[x].sum=tree[x].ch[1]=0;
if(x==tot)tot--;
}
int find(int v)
{
int now=root;
while(1)
{
if(tree[now].v==v){splay(now,root);return now;}
int nxt=v<tree[now].v?0:1;
if(!tree[now].ch[nxt])return 0;
now=tree[now].ch[nxt];
}
}
void pop(int v)
{
int deal=find(v);
if(!deal)return;
pointnum--;
if(tree[deal].rec>1){tree[deal].sum--;tree[deal].rec--;return;}
if(!tree[deal].ch[0])root=tree[deal].ch[1],tree[root].fa=0;
else
{
int le=tree[deal].ch[0];
while(tree[le].ch[1])le=tree[le].ch[1];
splay(le,tree[deal].ch[0]);
int ri=tree[deal].ch[1];
connect(ri,le,1);
connect(le,0,1);
update(le);
}
dele(deal);
}
void insert(int v)
{
int p=build(v);splay(p,root);
}
int rank(int v)
{
int ans=0,now=root;
while(1)
{
if(tree[now].v==v){ans+=tree[tree[now].ch[0]].sum+1;splay(now,root);return ans;}
if(now==0)return 0;
if(v<tree[now].v)now=tree[now].ch[0];
else ans+=tree[tree[now].ch[0]].sum+tree[now].rec,now=tree[now].ch[1];
}
}
int arank(int x)
{
int now=root;
while(1)
{
int used=tree[now].sum-tree[tree[now].ch[1]].sum;
if(x>tree[tree[now].ch[0]].sum&&x<=used)break;
if(x<used)now=tree[now].ch[0];
else x-=used,now=tree[now].ch[1];
}
splay(now,root);
return tree[now].v;
}
int lower(int v)
{
int now=root;
int ans=-100000000;
while(now)
{
if(tree[now].v<v&&tree[now].v>ans)ans=tree[now].v;
if(v>tree[now].v)now=tree[now].ch[1];
else now=tree[now].ch[0];
}
return ans;
}
int upper(int v)
{
int now=root;
int ans=100000000;
while(now)
{
if(tree[now].v>v&&tree[now].v<ans)ans=tree[now].v;
if(tree[now].v>v)now=tree[now].ch[0];
else now=tree[now].ch[1];
}
return ans;
}
int main()
{
//freopen("xf.in","r",stdin);
scanf("%d",&n);
int p1,p2;
for(int i=1;i<=n;i++)
{
p1=read();p2=read();
if(p1==1)insert(p2);
else if(p1==2)pop(p2);
else if(p1==3)printf("%d\n",rank(p2));
else if(p1==4)printf("%d\n",arank(p2));
else if(p1==5)printf("%d\n",lower(p2));
else if(p1==6)printf("%d\n",upper(p2));
}
return 0;
}