// 郁闷的出纳员
#include <iostream>
#include <cstdlib>
#define lc son[p][0]
#define rc son[p][1]
#define inf 0x7fffffff

using namespace std;

const int N = 3e5 + 37;
int n, minn, root, k, tot, cnt, ans, sum, idx;
int son[N][2], val[N], pri[N], siz[N];

void up(int p) {
	siz[p] = siz[lc] + siz[rc] + 1;
}

void split(int p, int v, int &l, int &r) {
    if (!p) {
        l = r = 0;
        return;
    }
    if (val[p] <= v) {
        l = p;
        split(rc, v, rc, r);
    } else {
        r = p;
        split(lc, v, l, lc);
    }
    up(p);
}

int merge(int l, int r) {
    if (!l || !r) return l + r;
    if (pri[l] > pri[r]) {
        son[l][1] = merge(son[l][1], r);
        up(l);
        return l;
    } else {
        son[r][0] = merge(l, son[r][0]);
        up(r);
        return r;
    }
}

void insert(int v) {
    int p = ++idx, l, r;
    split(root, v, l, r);
    val[p] = v;
    siz[p] = 1;
    pri[p] = rand();
    root = merge(merge(l, p), r);
}

void Delete(int v) {
    int l, r, mid;
    split(root, v, l, r);
    split(l, v - 1, l, mid);
    mid = merge(son[mid][0], son[mid][1]);
    root = merge(merge(l, mid), r);
}

int rnk(int v) {
    int l ,r;
    split(root, v - 1, l, r);
    int res = siz[l] + 1;
    root = merge(l, r);
    return res;
}

int kth(int p, int v) {
    if (siz[lc] >= v) return kth(lc, v);
    if (siz[lc] + 1 == v) return val[p];
    kth(rc, v - siz[lc] - 1);
}

int getpre(int v) {
    int l, r;
    split(root, v, l, r);
    int res = kth(l, siz[l]);
    root = merge(l, r);
    return res;
}

int getnext(int v) {
    int l, r;
    split(root, v, l, r);
    int res = kth(r, 1);
    root = merge(l, r);
    return res;
}

int main()
{
	cin >> n >> minn;
	insert(-inf);
	insert(inf);
	root = 1;
	son[1][1] = 2;
	up(root);
    
	while (n--) {
		char ch;
		cin >> ch >> k;
		if (ch == 'I') {
			if (k - sum < minn) continue;
			insert(k - sum);
 			cnt++;
			ans++;
		} else if (ch == 'A') {
			minn -= k;
			sum += k;
		} else if (ch == 'S') {
			minn += k;
			sum -= k;
			int a1 = minn - 1, a2;
			while (getpre(a1) != -inf) {
				a2 = a1;
				a1 = getpre(a1);
				Delete(getpre(a2));
				cnt--;
			}
		} else if (ch == 'F') {
			if (cnt < k) puts("-1");
			else printf("%d\n", rnk(cnt - k + 2) + sum);
		}
	}
	cout << ans - cnt;
	return 0;
}
/*
    shutdown
    没有参数   显示帮助。这与键入 /? 是一样的。
    /?         显示帮助。这与不键入任何选项是一样的。
    /i         显示图形用户界面(GUI)。
               这必须是第一个选项。
    /l         注销。这不能与 /m 或 /d 选项一起使用。
    /s         关闭计算机。
    /r         关闭并重新启动计算机。
    /g         关闭并重新启动计算机。系统重新启动后,
               重新启动所有注册的应用程序。
    /a         中止系统关闭。
               这只能在超时期间使用。
    /p         关闭本地计算机,没有超时或警告。
               可以与 /d 和 /f 选项一起使用。
    /h         休眠本地计算机。
               可以与 /f 选项一起使用。
    /e         记录计算机意外关闭的原因。
    /m \\computer 指定目标计算机。
    /t xxx     设置关闭前的超时为 xxx 秒。
               有效范围是 0-315360000 (10 年),默认值为 30。
               如果超时时间大于 0,则默示 /f
               参数。
    /c "comment" 重启动或关闭的原因的注释。
               最多允许 512 个字符。
    /f         强制正在运行的应用程序关闭,不前台警告用户。
               当为 /t 参数指定大于 0 的值时,
               则默示 /f 参数。
    /d [p|u:]xx:yy  提供重新启动或关机的原因。
               p 表明重新启动或关闭是计划内的。
               u 表示原因由用户定义。
               如果 p 和 u 均未指定,则是计划外重新启动
               或关闭。
               xx 是主要原因号(小于 256 的正整数)。
               yy 是次要原因号(小于 65536 的正整数)。
*/

1 条评论

  • 1