好多水题的题解忘了传……
直接Treap
#include<cstdio>
#include<cstdlib>
int n,mn,tag=0,root,leave=0,cnt;
char s[2];
struct Treap{
int l,r,v,rnd,siz,w;
}tree[100005];
void Pre(){
tree[0].l=0;
tree[0].r=0;
root=0;
cnt=0;
srand(123465);
}
void Pushup(int rt){
tree[rt].siz=tree[tree[rt].l].siz+tree[tree[rt].r].siz+tree[rt].w;
}
void Lr(int &p){
int q=tree[p].r;
tree[p].r=tree[q].l;
tree[q].l=p;
tree[q].siz=tree[p].siz;
Pushup(p);
p=q;
}
void Rr(int &p){
int q=tree[p].l;
tree[p].l=tree[q].r;
tree[q].r=p;
tree[q].siz=tree[p].siz;
Pushup(p);
p=q;
}
void Ins(int &rt,int x){
if(!rt){
rt=++cnt;
tree[rt].l=0;
tree[rt].r=0;
tree[rt].v=x;
tree[rt].siz=1;
tree[rt].w=1;
tree[rt].rnd=rand()<<15+rand();
return;
}
tree[rt].siz++;
if(tree[rt].v>x){
Ins(tree[rt].l,x);
if(tree[tree[rt].l].rnd<tree[rt].rnd)Rr(rt);
return;
}
else {
Ins(tree[rt].r,x);
if(tree[tree[rt].r].rnd<tree[rt].rnd)Lr(rt);
}
}
int Del(int &rt){
if(rt==0)return 0;
if(tree[rt].v+tag<0){
int temp=tree[tree[rt].l].siz+1;
rt=tree[rt].r;
return temp+Del(rt);
}
int temp=Del(tree[rt].l);
tree[rt].siz-=temp;
return temp;
}
int Find(int rt,int x){
if(rt==0)return 0;
if(x<=tree[tree[rt].l].siz)return Find(tree[rt].l,x);
else {
if(x>tree[tree[rt].l].siz+1)return Find(tree[rt].r,x-tree[tree[rt].l].siz-1);
return tree[rt].v+tag;
}
}
int main(){
freopen("1503.in","r",stdin);
freopen("1503.out","w",stdout);
scanf("%d %d",&n,&mn);
for(int i=1;i<=n;i++){
int Ts;
scanf("%s %d",s,&Ts);
if(s[0]=='I'){if(Ts>=mn){Ins(root,Ts-tag-mn);}}
if(s[0]=='A'){tag+=Ts;}
if(s[0]=='S'){tag-=Ts;leave+=Del(root);}
if(s[0]=='F'){if(Ts>tree[root].siz)puts("-1");else printf("%d\n",Find(root,tree[root].siz-Ts+1)+mn);}
}
printf("%d\n",leave);
return 0;
}