做法
平衡树基本操作 注意 一些细节
pushup 的顺序
splay的rotate顺序
pushup时应该加1
注意 边界 是l 所以应该是先插入极小值
#include <bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
#define fi first
#define se second
#define pb push_back
#define inf 1ll<<62
#define endl "\n"
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define de_bug(x) cerr << #x << "=" << x << endl
#define all(a) a.begin(),a.end()
#define IOS std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fer(i,a,b) for(int i=a;i<=b;i++)
#define der(i,a,b) for(int i=a;i>=b;i--)
const int mod = 1e9 + 7;
const int N = 6e6 + 10;
int n, m , k;
struct node {
int siz;
int l, r;
int val;
int fa;
int s[2];
#define ls(i) tr[i].s[0]
#define rs(i) tr[i].s[1]
#define fa(x) tr[x].fa
#define val(x) tr[x].val
} tr[N];
int rt;
void pushup(int i) {
tr[i].siz = tr[ls(i)].siz + tr[rs(i)].siz + 1;
}
void rotate(int x) {
int y = fa(x), z = fa(y);
int k = rs(y) == x;
tr[z].s[rs(z) == y] = x, fa(x) = z;
tr[y].s[k] = tr[x].s[k ^ 1], fa(tr[x].s[k ^ 1]) = y;
tr[x].s[k ^ 1] = y, fa(y) = x;
pushup(y);
pushup(x);
}
void splay(int x, int k) {
while(fa(x) != k) {
int y = fa(x);
int z = fa(y);
if(z != k) {
//折线
if(rs(z) == y ^ rs(y) == x) {
rotate(x);
} else rotate(y);
}
//直线
rotate(x);
}
if(!k) rt = x;
}
int idx;
void insert(int val) {
int u = rt;
int fa = 0;
while(u) {
fa = u;
u = tr[u].s[val > tr[u].val];
}
u = ++idx;
if(fa) tr[fa].s[tr[fa].val < val] = u;
fa(u) = fa;
val(u) = val;
tr[u].siz = 1;
splay(u, 0);
}
int get_node(int val) {
int u = rt;
int ans = 0;
while(u) {
if(val(u) >= val) {
ans = u;
u = ls(u);
} else u = rs(u);
}
return ans;
}
//第k大
int get_ans(int i, int k) {
if(tr[rs(i)].siz >= k) return get_ans(rs(i), k);
else if(tr[rs(i)].siz + 1 == k) return tr[i].val;
else {
return get_ans(ls(i), k - 1 - tr[rs(i)].siz);
}
}
//第k小
int get_ans1(int i, int k) {
if(tr[ls(i)].siz >= k) return get_ans1(ls(i), k);
else if(tr[ls(i)].siz + 1 == k) return tr[i].val;
else {
return get_ans1(rs(i), k - 1 - tr[ls(i)].siz);
}
}
int cnt;
void solve() {
insert(-(1 << 30));
insert((1 << 30));
int l = 1, r = 2;
cin >> n >> m;
int tmp = 0;
fer(i, 1, n) {
char op;
int x;
cin >> op >> x;
if(op == 'I') {
if(x < m)continue;
++cnt;
int t = x - tmp;
insert(t);
} else if(op == 'A') {
tmp += x;
} else if(op == 'S') {
tmp -= x;
int r = get_node(m - tmp);
splay(r, 0);
splay(l, r);
rs(l) = 0;
pushup(l);
pushup(r);
} else if(op == 'F') {
if(tr[rt].siz - 2 < x ) cout << -1 << endl;
else cout << get_ans1(rt, tr[rt].siz - x) + tmp << endl;
}
}
cout << cnt - tr[rt].siz + 2 << endl;
}
int main() {
IOS;
int _ = 1;
//cin>>_;
while( _-- )
solve();
}