我是题面

题意应该比较清晰,很明显,平衡树轻松应对,我用的是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\n",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\n",ans);
    return 0;
}