【题目链接】
【思路要点】
- 随便用个平衡树、线段树、块状链表、std::vector之类的数据结构维护一下就行了。
- 时间复杂度\(O(NLogN)\)或\(O(N\sqrt{N})\)。
【代码】
#include<stdio.h> #define MAXN 200000 struct data { int left, right, father, size, v, num; } tree[MAXN]; int n, m, l, tot, root, delta; void pushup(int x) { tree[x].size = tree[tree[x].left].size+tree[tree[x].right].size+1; } void zig(int &x) { int y = tree[x].father; int z = tree[y].father; if (y == tree[z].left) tree[z].left = x; else tree[z].right = x; tree[x].father = z; tree[y].left = tree[x].right; tree[tree[x].right].father = y; tree[x].right = y; tree[y].father = x; pushup(y); pushup(x); if (y == root) root = x; } void zag(int &x) { int y = tree[x].father; int z = tree[y].father; if (y == tree[z].left) tree[z].left = x; else tree[z].right = x; tree[x].father = z; tree[y].right = tree[x].left; tree[tree[x].left].father = y; tree[x].left = y; tree[y].father = x; pushup(y); pushup(x); if (y == root) root = x; } void splay(int &x) { while (tree[x].father != 0) { if (tree[tree[x].father].left == x) zig(x); else zag(x); } } void insert(int k) { if (root == 0) { root = ++tot; tree[tot].num = k; tree[tot].size = 1; return; } int p = root, z; while (p != 0) { z = p; tree[p].size++; if (k<tree[p].num) p = tree[p].left; else p = tree[p].right; } if (k<tree[z].num) tree[z].left = ++tot; else tree[z].right = ++tot; tree[tot].num = k; tree[tot].size = 1; tree[tot].father = z; splay(tot); } int dec(int &x, int f) { if (x == 0) return 0; int k; if (tree[x].num+delta<m) { k = dec(tree[x].right, x)+tree[tree[x].left].size+1; tree[tree[x].right].size = tree[x].size-k; x = tree[x].right; tree[x].father = f; } else { k = dec(tree[x].left, x); tree[x].size -= k; } return k; } int find(int &x, int k) { if (k <= tree[tree[x].right].size) return find(tree[x].right, k); if (k == tree[tree[x].right].size+1) return tree[x].num; return find(tree[x].left, k-tree[tree[x].right].size-1); } int main() { scanf("%d%d", &n, &m); int k; char c[1]; for (int i = 1; i <= n; i++) { scanf("%s%d", &c, &k); if (c[0] == 'I' and k >= m) insert(k-delta); if (c[0] == 'A') delta += k; if (c[0] == 'S') {delta -= k; l += dec(root, 0); }; if (c[0] == 'F') printf("%d\n", k <= tree[root].size?find(root, k)+delta:-1); } printf("%d\n", l); return 0; }