参考于AgOH大佬的递归版splay做法!!!
#include <bits/stdc++.h> using namespace std; #define ll long long #define re register const int N=1e6+10; void read(int &a) { a=0;int d=1;char ch; while(ch=getchar(),ch>'9'||ch<'0') if(ch=='-') d=-1; a=ch^48; while(ch=getchar(),ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48); a*=d; } struct note{int l,r,siz,cnt,val;}spl[N]; int rt,cnt; void newnode(int &now,int val) { spl[now=++cnt].val=val; spl[now].siz=1; spl[now].cnt=1; } void update(int now){spl[now].siz=spl[spl[now].l].siz+spl[spl[now].r].siz+spl[now].cnt;} void zig(int &now) { int l=spl[now].l; spl[now].l=spl[l].r; spl[l].r=now; now=l; update(spl[now].r),update(now); } void zag(int &now) { int r=spl[now].r; spl[now].r=spl[r].l; spl[r].l=now; now=r; update(spl[now].l),update(now); } void splaying(int x,int &y) { if(x==y) return; int &l=spl[y].l,&r=spl[y].r; if(x==l) zig(y); else if(x==r) zag(y); else if(spl[x].val<spl[y].val) { if(spl[x].val<spl[l].val) splaying(x,spl[l].l),zig(y),zig(y); else splaying(x,spl[l].r),zag(l),zig(y); } else { if(spl[x].val<spl[r].val) splaying(x,spl[r].l),zig(r),zag(y); else splaying(x,spl[r].r),zag(y),zag(y); } } void delnode(int now) { splaying(now,rt); if(spl[now].cnt>1) spl[now].cnt--,spl[now].siz--; else if(spl[now].r) { int p=spl[now].r; while(spl[p].l) p=spl[p].l; splaying(p,spl[now].r); spl[spl[rt].r].l=spl[rt].l; rt=spl[rt].r; update(rt); } else rt=spl[now].l; } void ins(int &now,int val) { if(!now) newnode(now,val),splaying(now,rt); else if(spl[now].val>val) ins(spl[now].l,val); else if(spl[now].val<val) ins(spl[now].r,val); else spl[now].cnt++,spl[now].siz++,splaying(now,rt); } void del(int &now,int val) { if(spl[now].val==val) delnode(now); else if(spl[now].val>val) del(spl[now].l,val); else del(spl[now].r,val); } int getnum(int rk) { int now=rt; while(now) { int lsiz=spl[spl[now].l].siz; if(lsiz+1<=rk&&rk<=lsiz+spl[now].cnt) { splaying(now,rt); break; } else if(lsiz>=rk) now=spl[now].l; else { rk-=lsiz+spl[now].cnt; now=spl[now].r; } } return spl[now].val; } int getrank(int val) { int now=rt,rk=1; while(now) { if(spl[now].val==val) { rk+=spl[spl[now].l].siz; splaying(now,rt); break; } else if(spl[now].val>val) now=spl[now].l; else { rk+=spl[now].cnt+spl[spl[now].l].siz; now=spl[now].r; } } return rk; } int main() { int n;read(n); for(re int i=1,op,x;i<=n;i++) { read(op),read(x); if(op==1) ins(rt,x); else if(op==2) del(rt,x); else if(op==3) printf("%d\n",getrank(x)); else if(op==4) printf("%d\n",getnum(x)); else if(op==5) printf("%d\n",getnum(getrank(x)-1)); else printf("%d\n",getnum(getrank(x+1))); } return 0; }