PS:SPLAY依然不能一次写对…… 总会写出毛病,真是醉醉醉醉醉……
这题难点在于变动工资,我们只需要变动工资K,表示工资现在增加了K。 然后如果有员工进来,【并且进的来,初始工资比最低工资高】,那么我们就把这个员工的工资,减去K这个值,加入到平衡树中。
删人的的时候,只要查比【初始工资+工资变化量K】小的数字全删掉。 这里不需要一个一个删,大多数平衡树都会支持删整棵树的操作的~ 就直接把比那个值小的整棵树都删掉即可。
#include <iostream> #include <cstdio> #include <cstdlib> using namespace std; const int maxint = 0x7fffffff; struct node { node *c[2]; int key; int size; node() { key = size = 0; c[0] = c[1] = this; } node(int KEY_, node *c0, node *c1) { key = KEY_; c[0] = c0; c[1] = c1; } node* rz(){return size = c[0]->size + c[1]->size + 1, this;} }Tnull, *null = &Tnull; struct splay { node *root; splay () { root = (new node(*null)) -> rz(); root -> key = maxint; } inline void zig(int d) { node *t = root -> c[d]; root -> c[d] = null -> c[d]; null -> c[d] = root; root = t; } inline void zigzig(int d) { node *t = root -> c[d] -> c[d]; root -> c[d] -> c[d] = null -> c[d]; null -> c[d] = root -> c[d]; root -> c[d] = null -> c[d] -> c[!d]; null -> c[d] -> c[!d] = root -> rz(); root = t; } inline void finish(int d) { node *t = null -> c[d], *p = root -> c[!d]; while (t != null) { t = null -> c[d] -> c[d]; null -> c[d] -> c[d] = p; p = null -> c[d] -> rz(); null -> c[d] = t; } root -> c[!d] = p; } inline void select(int k) { int t; while (1) { bool d = k > (t = root -> c[0] ->size); if (k == t || root -> c[d] == null) break; if (d) k -= t+ 1; bool dd = k > (t = root -> c[d] -> c[0] -> size); if (k == t || root -> c[d] -> c[dd] == null) {zig(d); break;} if (dd) k-= t+1; d != dd ? zig(d), zig(dd) : zigzig(d); } finish(0), finish(1); root -> rz(); } inline void search(int x) { while (1) { bool d = x > root -> key; if (root -> c[d] == null) break; bool dd = x > root -> c[d] -> key; if (root -> c[d] -> c[dd] == null) {zig(d); break;} d != dd? zig(d), zig(dd) : zigzig(d); } finish(0), finish(1); root -> rz(); if (x > root -> key) select(root -> c[0] -> size + 1); } inline void ins(int x) { search(x); node *oldroot = root; root = new node(x, oldroot -> c[0], oldroot); oldroot -> c[0] = null; oldroot -> rz(); root -> rz(); } inline void del(int x) { search(x); node *oldroot = root; root = root -> c[1]; select(0); root -> c[0] = oldroot -> c[0]; root -> rz(); delete oldroot; } int sel(int k) {return select(k -1), root->key;} int ran(int x){return search(x), root -> c[0] -> size + 1;} }sp; int limit, n; int main() { scanf("%d%d", &n, &limit); char flag; int tmp, biandong=0; int away = 0; while (n--) { scanf("\n%c%d", &flag, &tmp); if (flag == 'I') { tmp -= limit; if (tmp < 0)//一开始给的工资就不足 { /*尼玛! 为毛这不算离开公司? “他就会立刻气愤地离开公司” 这难道不算“离开公司的员工的总数”。 因为他不算员工么!?*/ //++away; continue; } sp.ins(tmp + biandong); } if (flag == 'A') biandong -= tmp; if (flag == 'S') { biandong += tmp; sp.ran(biandong); away += sp.root -> c[0] -> size ; sp.root -> c[0] = null; sp.root -> rz(); } if (flag == 'F') { if (tmp > sp.root -> size -1) { printf("-1\n"); continue; } printf("%d\n", sp.sel(sp.root -> size - tmp) + limit - biandong); } } printf("%d\n", away); return 0; }