本蒟蒻刚学平衡树。
旋转 Treap
, 20RE+80WA
。
#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
int n,m,a,k,tx,ans;
char o;
struct Trp{
int x,num,siz,rk;
Trp *ch[2];
Trp(int val):x(val),num(1),siz(1){
ch[0]=ch[1]=nullptr;
rk=rand();
}
void cpt_size(){
siz=num+(ch[0]==nullptr?0:ch[0]->siz)+(ch[1]==nullptr?0:ch[1]->siz);
}
};
void rot(Trp *&p,int t){
Trp *tmp=p->ch[!t];
if(tmp==nullptr)return;
p->ch[!t]=tmp->ch[t];
tmp->ch[t]=p;
p->cpt_size();
tmp->cpt_size();
p=tmp;
}
void insert(Trp *&p,int x){
if(p==nullptr){
p=new Trp(x);
return;
}
if(p->x==x){
p->num++;
p->cpt_size();
return;
}
if(p->x>x){
insert(p->ch[0],x);
if(p->rk>p->ch[0]->rk)rot(p,1);
return;
}
if(p->x<x){
insert(p->ch[1],x);
if(p->rk>p->ch[1]->rk)rot(p,0);
return;
}
}
void del(Trp *&p){
ans+=p->num;
if(p->ch[0]==nullptr && p->ch[1]==nullptr){
delete p;
p=nullptr;
return;
}
if(p->ch[0]!=nullptr && p->ch[1]==nullptr){
Trp *tmp=p;
p=p->ch[0];
delete tmp;
p->cpt_size();
return;
}
if(p->ch[0]==nullptr && p->ch[1]!=nullptr){
Trp *tmp=p;
p=p->ch[1];
delete tmp;
p->cpt_size();
return;
}
if(p->ch[0]!=nullptr && p->ch[1]!=nullptr){
int t=p->ch[0]->rk>p->ch[1]->rk;
rot(p,t);
del(p->ch[t]);
p->cpt_size();
return;
}
}
int rkf(Trp *&p,int c){
if(p->siz<c)return -1;
int rs=(p->ch[1]==nullptr?0:p->ch[1]->siz);
if(rs>=c)return rkf(p->ch[1],c);
if(rs+p->num>=c)return p->x;
return rkf(p->ch[0],c-rs-p->num);
}
void upd(Trp *&p){
if(p==nullptr)return;
if(p->x+k<m){
upd(p->ch[0]);
upd(p->ch[1]);
del(p);
return;
}
if(p->x+k>=m){
upd(p->ch[0]);
p->cpt_size();
return;
}
}
int main(){
Trp *trp=nullptr;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf(" %c %d",&o,&a);
if(o=='I' && a>=m)insert(trp,a-k);
if(o=='A')k+=a;
if(o=='S')k-=a,upd(trp);
if(o=='F'){
tx=rkf(trp,a);
if(tx==-1)printf("-1\n");
else printf("%d\n",rkf(trp,a)+k);
}
}
printf("%d",ans);
return 0;
}