解析: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 ",rank(p2)); else if(p1==4)printf("%d ",arank(p2)); else if(p1==5)printf("%d ",lower(p2)); else if(p1==6)printf("%d ",upper(p2)); } return 0; }