-
操作中涉及到将所有员工的工资都增加,容易想到用一个全局变量 $\Delta$ 来维护
$\text{splay}$ 中维护的值为 $x$,那么员工真实的工资数值为 $x + \Delta$ -
招员工和员工离职,就是 $\text{splay}$ 中常见的添加,删除操作
-
比较难处理的是员工离职的情况,员工工资 $x + \Delta < \min$ 最低工资标准会离职
-
在 splay 两端加入两个哨兵,$-\infty, \ +\infty$,splay 执行删除区间操作
待删区间的左端点就是 $L = -\infty$,右端点是第一个满足 $t_R.v \geqslant \min-\Delta$ 的 $R$
删除 $[L, R]$ 区间,将 $R$ splay 到根,并且将 $L$ splay 成 $R$ 的儿子,删除 $R$ 右子树即可 -
找到 $\geqslant \min - \Delta$ 的最小数,实际上就是执行平衡二叉树的二分查找
如果根节点 $u$ 满足, $u$ 是备选答案,接着去 $u$ 的左子树尝试找更小的
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
int n, m, L, R, delta = 0;
// get_k return dat
class Splay {
public:
struct node {
int son[2], pa, sz;
int dat;
void init(int _pa, int _dat) {
pa = _pa, dat = _dat;
sz = 1;
}
};
int tot;
int idx = 0, root = 0;
vector<node> t;
Splay() = default;
Splay(int _tot) : tot(_tot) {
t.resize(tot);
idx = 0, root = 0;
}
inline void pull(int u) {
t[u].sz = t[t[u].son[0]].sz + t[t[u].son[1]].sz + 1;
}
void rotate(int x) {
int y = t[x].pa, z = t[y].pa;
int k = t[y].son[1] == x;
t[z].son[t[z].son[1] == y] = x, t[x].pa = z;
t[y].son[k] = t[x].son[k^1], t[t[x].son[k^1]].pa = y;
t[x].son[k^1] = y, t[y].pa = x;
pull(y), pull(x);
}
void splay(int x, int k) {
while (t[x].pa != k) {
int y = t[x].pa, z = t[y].pa;
if (z != k) {
if ((t[y].son[1] == x) ^ (t[z].son[1] == y)) rotate(x);
else rotate(y);
}
rotate(x);
}
if (k == 0) root = x;
}
int insert(int v) {
int u = root, p = 0;
while (u) p = u, u = t[u].son[v > t[u].dat];
u = ++idx;
if (p) t[p].son[v > t[p].dat] = u;
t[u].init(p, v);
splay(u, 0);
return u;
}
int find(int x) {
int u = root, res;
while (u) {
if (t[u].dat >= x) res = u, u = t[u].son[0];
else u = t[u].son[1];
}
return res;
}
int get_k(int k) {
int u = root;
while (u) {
if (t[t[u].son[0]].sz >= k) u = t[u].son[0];
else if (t[t[u].son[0]].sz + 1 == k) return t[u].dat;
else k -= t[t[u].son[0]].sz + 1, u = t[u].son[1];
}
return -1;
}
} spl(maxn);
int main() {
freopen("input.txt", "r", stdin);
scanf("%d%d", &n, &m);
// build
L = spl.insert(-inf), spl.insert(inf);
int tot = 0;
for (int i = 0; i < n; i++) {
char op[2];
int k;
scanf("%s%d", op, &k);
// get data
if (op[0] == 'I') {
if (k >= m) tot++, k -= delta, spl.insert(k);
}
else if (op[0] == 'A') {
delta += k;
}
else if (op[0] == 'S') {
delta -= k;
R = spl.find(m - delta);
spl.splay(R, 0), spl.splay(L, R);
spl.t[L].son[1] = 0;
spl.pull(L), spl.pull(R);
}
else {
// F
if (k > spl.t[spl.root].sz - 2) puts("-1");
else {
int res = spl.get_k(spl.t[spl.root].sz - k);
printf("%d\n", res + delta);
}
}
}
printf("%d\n", tot - spl.t[spl.root].sz + 2);
}