1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| #include <iostream> #include <cstdio> #include <random> #include <ctime> #include <limits.h> #define LL long long using namespace std;
namespace SHAWN { const int N = 2e5 + 7; mt19937 rd(time(nullptr)); namespace Treap { #define ls son[ro][1] #define rs son[ro][0] int cont, root; int son[N][2], pre[N], size[N], cnt[N]; LL val[N]; void update(int ro) { if (!ro) { return; } size[ro] = cnt[ro]; if (ls) { size[ro] += size[ls]; } if (rs) { size[ro] += size[rs]; } } void rotate(int ro, int fa, int opt) { int s = son[ro][opt]; son[ro][opt] = son[s][!opt]; son[s][!opt] = ro; if (!fa) { root = s; } else { son[fa][son[fa][1] == ro] = s; } update(ro); update(s); } void insert(int ro, int fa, LL x) { if (!ro) { ro = ++cont; cnt[ro] = 1; val[ro] = x; pre[ro] = rd() % INT_MAX; update(ro); if (!fa) { root = ro; } else { son[fa][x < val[fa]] = ro; } } else { if (x == val[ro]) { ++cnt[ro]; update(ro); } else if (x < val[ro]) { insert(ls, ro, x); update(ro); if (pre[ls] < pre[ro]) { rotate(ro, fa, 1); } } else { insert(rs, ro, x); update(ro); if (pre[rs] < pre[ro]) { rotate(ro, fa, 0); } } } } void del(int ro, int fa, LL x) { if (!ro) { return; } if (x == val[ro]) { --cnt[ro]; if (!cnt[ro]) { int f = fa, s; update(ro); while(ls && rs) { if (pre[ls] < pre[rs]) { s = ls; rotate(ro, f, 1); f = s; } else { s = rs; rotate(ro, f, 0); f = s; } } while (ls) { s = ls; rotate(ro, f, 1); f = s; } while (rs) { s = rs; rotate(ro, f, 0); f = s; } if (root == ro) { root = 0; } else { son[f][son[f][1] == ro] = 0; } } update(ro); } else { if (x < val[ro]) { del(ls, ro, x); update(ro); } else { del(rs, ro, x); update(ro); } } } LL find_pre(int ro, LL x) { if (!ro) { return LONG_LONG_MIN; } else if (x > val[ro]) { return max(val[ro], find_pre(rs, x)); } else { return find_pre(ls, x); } } LL get_num(int ro, int x) { if (x <= size[ls]) { return get_num(ls, x); } else if (x <= size[ls] + cnt[ro]) { return val[ro]; } else { return get_num(rs, x - size[ls] - cnt[ro]); } } void insert(LL x) { insert(root, 0, x); } void del(LL x) { del(root, 0, x); } LL findpre(LL x) { return find_pre(root, x); } LL getnum(int x) { return get_num(root, x); } #undef ls #undef rs }
int n; LL _min, tag, cnt, sum; signed work() { cin >> n >> _min; for (int i = 1; i <= n; ++i) { char opt; LL k; cin >> opt >> k; if (opt == 'I') { if (k - tag >= _min) { Treap :: insert(k - tag); ++cnt; ++sum; } } else if (opt == 'A') { _min -= k; tag += k; } else if (opt == 'S') { _min += k; tag -= k; LL tmp; while ((tmp = Treap :: findpre(_min)) != LONG_LONG_MIN) { Treap :: del(tmp); --cnt; } } else if (opt == 'F') { if (cnt < k) { cout << "-1\n"; } else { cout << Treap :: getnum(cnt - k + 1) + tag << '\n'; } } } cout << sum - cnt << '\n'; return 0; } }
signed main() { ios :: sync_with_stdio(false); cin.tie(nullptr); return SHAWN :: work(); }
|