BZOJ 1503 splay
平衡树基本操作
//By SiriusRen #include <bits/stdc++.h> using namespace std; const int N=200050; int n,minn,xx,root,fa[N],ch[N][2],size[N],cnt[N],w[N],sum,top,delta; char op[10]; void push_up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+cnt[x];} void rotate(int p){ int q=fa[p],y=fa[q],f=(ch[q][1]==p); ch[q][f]=ch[p][!f],fa[ch[q][f]]=q; ch[p][!f]=q,fa[q]=p,fa[p]=y; if(y)ch[y][ch[y][1]==q]=p; push_up(q); } void splay(int x,int tp){ for(int y;y=fa[x];rotate(x)){ if(y==tp)break; if(fa[y]!=tp){ if((ch[y][1]==x)^(ch[fa[y]][1]==y))rotate(x); else rotate(y); } }push_up(x); if(!tp)root=x; } void ins(int &pos,int f,int wei){ if(!pos)pos=++top,fa[pos]=f,w[pos]=wei,size[pos]=cnt[pos]=1,splay(pos,0); else if(wei==w[pos])cnt[pos]++,size[pos]++,splay(pos,0); else if(wei<w[pos])ins(ch[pos][0],pos,wei); else ins(ch[pos][1],pos,wei); } void del(int &pos,int f,int wei){ if(!pos)return; if(w[pos]>=wei)del(ch[pos][0],pos,wei); else{ sum+=size[ch[pos][0]]+cnt[pos],pos=ch[pos][1],fa[pos]=f; if(!f)root=pos;del(pos,f,wei); }push_up(pos); } int kth(int x,int k){ if(size[ch[x][1]]>=k)return kth(ch[x][1],k); else if(size[ch[x][1]]+cnt[x]<k)return kth(ch[x][0],k-size[ch[x][1]]-cnt[x]); else return w[x]; } int main(){ scanf("%d%d",&n,&minn); for(int i=1;i<=n;i++){ scanf("%s%d",op,&xx); if(op[0]=='I'){if(xx>=minn)ins(root,0,xx-delta);} else if(op[0]=='A')delta+=xx; else if(op[0]=='S')delta-=xx,del(root,0,minn-delta); else printf("%d\n",xx>size[root]?-1:kth(root,xx)+delta); }printf("%d\n",sum); }