http://www.lydsy.com/JudgeOnline/problem.php?id=1503
都是些基本的平衡树操作,各种平衡树都可以,我用的splay
//插入,删除(一棵子树),找第k大 #include<cstdio> const int inf = ~0u>>2; #define KT (ch[ ch[rt][1] ][0]) const int maxn = 200010; int lim; struct SplayTree { int sz[maxn]; int ch[maxn][2]; int pre[maxn]; int rt,top; inline void up(int x){ sz[x] = cnt[x] + sz[ ch[x][0] ] + sz[ ch[x][1] ]; } inline void Rotate(int x,int f){ int y=pre[x]; ch[y][!f] = ch[x][f]; pre[ ch[x][f] ] = y; pre[x] = pre[y]; if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x; ch[x][f] = y; pre[y] = x; up(y); } inline void Splay(int x,int goal){//将x旋转到goal的下面 while(pre[x] != goal){ if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x); else { int y=pre[x],z=pre[y]; int f = (ch[z][0]==y); if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f); else Rotate(y,f),Rotate(x,f); } } up(x); if(goal==0) rt=x; } inline void RTO(int k,int goal){//将第k位数旋转到goal的下面 int x=rt; while(sz[ ch[x][0] ] != k-1) { if(k < sz[ ch[x][0] ]+1) x=ch[x][0]; else { k-=(sz[ ch[x][0] ]+1); x = ch[x][1]; } } Splay(x,goal); } inline void vist(int x){ if(x){ printf("结点%2d : 左儿子 %2d 右儿子 %2d %2d sz=%d\n",x,ch[x][0],ch[x][1],val[x],sz[x]); vist(ch[x][0]); vist(ch[x][1]); } } inline void Newnode(int &x,int c){ x=++top; ch[x][0] = ch[x][1] = pre[x] = 0; sz[x]=1; cnt[x]=1; val[x] = c; } inline void init(){ sum=ch[0][0]=ch[0][1]=pre[0]=sz[0]=0; rt=top=0; cnt[0]=0; } inline void Insert(int &x,int key,int f){ if(!x) { Newnode(x,key); pre[x]=f; Splay(x,0); return ; } if(key==val[x]){ cnt[x]++; sz[x]++; Splay(x,0); return ; }else if(key<val[x]) { Insert(ch[x][0],key,x); } else { Insert(ch[x][1],key,x); } up(x); } void del(int &x,int f){ if(!x) return ; if(val[x]>=lim){ del(ch[x][0],x); } else { sum+=sz[ch[x][0]]+cnt[x]; x=ch[x][1]; pre[x]=f; if(f==0) rt=x; del(x,f); } if(x) up(x); } inline void update(){ del(rt,0); } inline int find_kth(int x,int k){ if(k<sz[ch[x][0]]+1) { return find_kth(ch[x][0],k); }else if(k > sz[ ch[x][0] ] + cnt[x] ) return find_kth(ch[x][1],k-sz[ch[x][0]]-cnt[x]); else{ Splay(x,0); return val[x]; } } int cnt[maxn]; int val[maxn]; int sum; }spt; int main(){ int n; char op[5]; scanf("%d%d",&n,&lim); int lim0=lim; spt.init(); while(n--){ int k; scanf("%s%d",op,&k); if(op[0]=='I'){ if(k<lim0) {continue;} spt.Insert(spt.rt,k+lim-lim0,0); } else if(op[0]=='A'){ lim-=k; }else if(op[0]=='S'){ lim+=k; if(spt.sz[spt.rt]>0) spt.update(); } else { int sz=spt.sz[spt.rt]; if(k>sz) printf("-1\n"); else { printf("%d\n",spt.find_kth(spt.rt,sz-k+1)-lim+lim0); } } // spt.vist(spt.rt); } printf("%d\n",spt.sum); return 0; }