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;
}