郁闷的出纳员
题目描述
思路
Treap树 + 延迟标记
代码
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cstdlib>
const int MAX = 1e5 + 5;
int n, m, rt, tot, pt;
char str[5];
int ans, inf = 0x3f3f3f3f;
struct Node {
int lc, rc, cnt, size, pri, key, tag;
#define lc(x) t[x].lc
#define rc(x) t[x].rc
#define cnt(x) t[x].cnt
#define size(x) t[x].size
#define pri(x) t[x].pri
#define key(x) t[x].key
#define tag(x) t[x].tag
#define add(x) t[x].add
}t[MAX];
void pushdown(int r) {
if (!tag(r)) return;
if (lc(r)) {
key(lc(r)) += tag(r);
tag(lc(r)) += tag(r);
}
if (rc(r)) {
key(rc(r)) += tag(r);
tag(rc(r)) += tag(r);
}
tag(r) = 0;
}
void pushup(int r) {
size(r) = size(lc(r)) + size(rc(r)) + cnt(r);
}
void zig(int &r) {
pushdown(r);
pushdown(lc(r));
int s = lc(r);
lc(r) = rc(s);
rc(s) = r;
size(s) = size(r);
pushup(r);
r = s;
}
void zag(int &r) {
pushdown(r);
pushdown(rc(r));
int s = rc(r);
rc(r) = lc(s);
lc(s) = r;
size(s) = size(r);
pushup(r);
r = s;
}
void show(int x) {
printf("%d %d %d %d %d %3d\n", size(x), lc(x), rc(x), key(x), pri(x), tag(x));
if (lc(x)) show(lc(x));
if (rc(x)) show(rc(x));
}
void insert(int &r, int k) {
if (!r) {
r = ++tot;
pri(r) = rand(), key(r) = k;
lc(r) = rc(r) = 0;
size(r) = cnt(r) = 1;
tag(r) = 0;
return;
}
pushdown(r);
if (k == key(r)) ++cnt(r), pushup(r);
else if(k < key(r)) {
insert(lc(r), k);
pushup(r);
if (pri(lc(r)) < pri(r)) zig(r);
} else {
insert(rc(r), k);
pushup(r);
if (pri(rc(r)) < pri(r)) zag(r);
}
}
int del (int &r, int k) {
int res = 0;
pushdown(r);
if (k >= key(r)) {
if (rc(r) != 0) {
pushdown(rc(r));
zag(r);
res = del(r, k);
pushup(r);
return res;
} else {
res = size(r);
r = 0;
return res;
}
}
res = del(lc(r), k);
pushup(r);
return res;
}
int queryPre(int k) {
int r = rt, res = inf;
while (r) {
pushdown(r);
if (k >= key(r)) res = key(r), r = rc(r);
else r = lc(r);
}
return res;
}
int queryKth(int k) {
int r = rt, res = inf;
if (size(r) < k) return inf;
while (r) {
pushdown(r);
if (size(rc(r)) < k && size(rc(r)) + cnt(r) >= k) return key(r);
else if (size(rc(r)) >= k) r = rc(r);
else {
k -= size(rc(r)) + cnt(r);
r = lc(r);
}
}
return res;
}
inline int read() {
int s = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * f;
}
int main() {
srand(time(NULL));
n = read(), m = read();
for (int i = 1, j, k; i <= n; ++i) {
scanf("%s", str), j = read();
// printf("%s %d\n", str, j);
if (str[0] == 'I') {
if (j >= m) insert(rt, j);
} else if (str[0] == 'A') {
tag(rt) += j;
key(rt) += j;
} else if (str[0] == 'S') {
tag(rt) -= j;
key(rt) -= j;
k = queryPre(m - 1);
if (k != inf) ans += del(rt, k);
} else if (str[0] == 'F') {
k = queryKth(j);
if (k != inf) printf("%d\n", k);
else printf("-1\n");
}
}
printf("%d\n", ans);
return 0;
}