题意应该比较清晰,很明显,平衡树轻松应对,我用的是Splay
对于新建操作,我们可以记录之前对工资的调整(sum),在平衡树中插入(k-sum)即可,别忘了判断(k)是否大于等于(min)
对于增加操作,我们给(sum)加上(k)即可
对于减小操作,我们给(sum)减去(k),然后需要判断一下是否有人离开,直接删去树上权值小于(min-k)的点即可
对于查询操作,常规操作,不多说了
最后还要求我们输出一个离开的人,我们记录实际加入过平衡树的点的数量,减去最后剩余的点的数量即可
下面放代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#define ll long long
#define gc getchar
#define maxn 100005
using namespace std;
inline ll read(){
ll a=0;int f=0;char p=gc();
while(!isdigit(p)){f|=p=='-';p=gc();}
while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
return f?-a:a;
}int n,m,ans,sum;
struct ahaha{
int v,sz,cnt,ch[2];
}t[maxn];int rt,tot,f[maxn];
#define lc t[i].ch[0]
#define rc t[i].ch[1]
inline int get(int x){return x==t[f[x]].ch[1];}
inline void update(int i){
t[i].sz=t[i].cnt+t[lc].sz+t[rc].sz;
}
inline void clear(int i){
t[i].v=t[i].sz=t[i].cnt=f[i]=0;
}
inline int newnode(int v){
int i=++tot;t[i].v=v;
t[i].sz=t[i].cnt=1;
return i;
}
inline void rotate(int x){
int y=f[x],z=f[y],k=get(x);
f[x]=z;f[t[x].ch[k^1]]=y;f[y]=x;
if(z)t[z].ch[y==t[z].ch[1]]=x;
t[y].ch[k]=t[x].ch[k^1];t[x].ch[k^1]=y;
update(y);update(x);
}
void Splay(int x,int tar){
for(int y=f[x];(y=f[x])!=tar;rotate(x))
if(f[y]!=tar)rotate(get(y)==get(x)?y:x);
if(!tar)rt=x;
}
inline void insert(int v){
int i=rt,k;
if(!rt){rt=newnode(v);return;}
while(1){
if(v==t[i].v){
++t[i].cnt;
Splay(i,0);return;
}
k=v>t[i].v;
if(!t[i].ch[k]){
t[i].ch[k]=newnode(v);f[t[i].ch[k]]=i;
Splay(t[i].ch[k],0);return;
}
i=t[i].ch[k];
}
}
int find(int v){
int i=rt,sum=0;
while(1){
if(v<t[i].v){i=lc;if(!i)return sum;}
else{
sum+=t[lc].sz;
if(!rc||v==t[i].v){
if(v>t[i].v)sum+=t[i].cnt;
Splay(i,0);return sum+1;
}
sum+=t[i].cnt;i=rc;
}
}
}
int find_k(int k){
int i=rt;
while(1){
if(k<=t[lc].sz)i=lc;
else{
k-=t[lc].sz;
if(k<=t[i].cnt){
Splay(i,0);
return t[i].v;
}
k-=t[i].cnt;i=rc;
}
}
}
inline void del(int v){
find(v);int old=rt,i=t[rt].ch[0];
if(t[rt].cnt!=1){--t[rt].cnt;--t[rt].sz;return;}
if(t[rt].sz==1){clear(rt);rt=0;return;}
if(!t[rt].ch[0]){rt=t[rt].ch[1];f[rt]=0;clear(old);return;}
if(!t[rt].ch[1]){rt=t[rt].ch[0];f[rt]=0;clear(old);return;}
while(rc)i=rc;Splay(i,0);
t[rt].ch[1]=t[old].ch[1];f[t[old].ch[1]]=rt;
clear(old);update(rt);
}
inline void solve_1(){
int v=read();if(v<m)return;
insert(v-sum);++ans;
}
inline void solve_2(){
int x=read();
sum+=x;
}
inline void solve_3(){
int v=read();
sum-=v;insert(m-sum);
find(-100000000);
int x=rt;find(m-sum);int y=rt;
Splay(x,0);Splay(y,x);t[y].ch[0]=0;
update(y);update(x);del(m-sum);
}
inline void solve_4(){
int k=read();
if(t[rt].sz-2<k){
puts("-1");
return;
}
printf("%d
",find_k(t[rt].sz-k)+sum);
}
char s[5];
int main(){
n=read();m=read();
insert(100000000);insert(-100000000);
while(n--){
scanf("%s",s+1);
switch(s[1]){
case 'I':solve_1();break;
case 'A':solve_2();break;
case 'S':solve_3();break;
case 'F':solve_4();break;
}
}
ans-=t[rt].sz-2;
printf("%d
",ans);
return 0;
}