# 题意

1. 插入一个数
2. 所有数同时加一个数
3. 所有数同时减一个数，同时如果有数小于一个值，那么这个数应该被删除。
4. 查找第k大数
5. 统计被删除的数的总数

# 注意

pushdown函数虽然简单但是要反复检查。

# 代码

#include <cctype>
#include <cstdio>
const int maxn = 100010;
int ch[maxn][2], data[maxn], fa[maxn], cnt[maxn], size[maxn], ad[maxn],
dc[maxn];
int sz = 0, rt = 0;
int n, m, total = 0;
void update(int x) { size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x]; }
void pushdown(int x) {
if (ad[x] != 0 || dc[x] != 0) {
int l = ch[x][0], r = ch[x][1];
if (l == 0 && r == 0) {
data[x] -= dc[x];
dc[x] = 0;
return;
}
if (l != 0) {
dc[l] += dc[x];
}
if (r != 0) {
dc[r] += dc[x];
}
data[x] -= dc[x];
ad[x] = dc[x] = 0;
return;
}
}
void zig(int x) {
pushdown(x);
int y = fa[x], z = fa[y], l = (ch[y][1] == x), r = l ^ 1;
fa[ch[y][l] = ch[x][r]] = y;
fa[ch[x][r] = y] = x;
fa[x] = z;
ch[z][ch[z][1] == y] = x;
update(y);
}
void splay(int x, int aim = 0) {
for (int y; (y = fa[x]) != aim; zig(x))
if (fa[y] != aim)
zig((((ch[y][0] == x) == (ch[fa[y]][0] == y))) ? y : x);
if (aim == 0)
rt = x;
update(x);
}
void insert(int v) {
int x = rt;
if (rt == 0) {
rt = x = ++sz;
data[x] = v;
cnt[x] = size[x] = 1;
fa[x] = ch[x][0] = ch[x][1] = 0;
return;
}
while (x) {
size[x]++;
pushdown(x);
if (v == data[x]) {
cnt[x]++;
return;
}
int &y = ch[x][v > data[x]];
if (y == 0) {
y = ++sz;
data[y] = v;
size[y] = cnt[y] = 1;
fa[y] = x;
ch[y][0] = ch[y][1] = 0;
ch[x][v > data[x]] = y;
x = y;
break;
}
x = y;
}
splay(x);
}
void add(int x) {
pushdown(rt);
}
void dec(int x) {
pushdown(rt);
dc[rt] = x;
}
void fire() {
int x = rt;
int y = -1;
while (x) {
pushdown(x);
if (data[x] < m) {
x = ch[x][1];
} else {
y = x;
x = ch[x][0];
}
}
if (y == -1) {
total += size[rt];
rt = 0;
return;
}
splay(y);
total += size[ch[rt][0]];
ch[rt][0] = 0;
update(rt);
}
int kth(int v) {
if (v > size[rt])
return -1;
int x = rt;
while (x) {
pushdown(x);
if (v >= size[ch[x][1]] + 1 && v <= size[ch[x][1]] + cnt[x])
return data[x];
if (v > size[ch[x][1]] + cnt[x]) {
v -= size[ch[x][1]] + cnt[x];
x = ch[x][0];
} else
x = ch[x][1];
}
}
int main() {
#ifdef D
freopen("input", "r", stdin);
#endif
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
char opt = getchar();
while (!isalpha(opt))
opt = getchar();
;
if (opt == 'I') {
int x;
scanf("%d", &x);
if (x >= m)
insert(x);
} else if (opt == 'A') {
int x;
scanf("%d", &x);
} else if (opt == 'S') {
int x;
scanf("%d", &x);
dec(x);
fire();
} else if (opt == 'F') {
int x;
scanf("%d", &x);
printf("%d\n", kth(x));
}
}
printf("%d\n", total);
}


posted on 2017-02-28 17:31  蒟蒻konjac  阅读(177)  评论(0编辑  收藏  举报