BZOJ 1503 郁闷的出纳员
Description
OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?
Input
Output
输出文件的行数为F命令的条数加一。对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,如果k大于目前员工的数目,则输出-1。输出文件的最后一行包含一个整数,为离开公司的员工的总数。
Sample Input
9 10
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2
Sample Output
10
20
-1
2
20
-1
2
HINT
I命令的条数不超过100000 A命令和S命令的总条数不超过100 F命令的条数不超过100000 每次工资调整的调整量不超过1000 新员工的工资不超过100000
Source
平衡树大裸题,练习了一下sbt。
1 #include<cstdio> 2 #include<cstdlib> 3 using namespace std; 4 #define maxn 100010 5 struct SBT 6 { 7 int l,r,sz,key; 8 void init(){l = r = key = 0;sz = 1;} 9 }tree[maxn]; 10 int root,tot; 11 inline void zag(int &rt) 12 { 13 int k = tree[rt].r; 14 tree[rt].r = tree[k].l; 15 tree[k].l = rt; 16 tree[k].sz = tree[rt].sz; 17 tree[rt].sz = tree[tree[rt].l].sz+tree[tree[rt].r].sz+1; 18 rt = k; 19 } 20 inline void zig(int &rt) 21 { 22 int k = tree[rt].l; 23 tree[rt].l = tree[k].r; 24 tree[k].r = rt; 25 tree[k].sz = tree[rt].sz; 26 tree[rt].sz = tree[tree[rt].l].sz+tree[tree[rt].r].sz+1; 27 rt = k; 28 } 29 inline void maintain(int &rt,int flag) 30 { 31 if (flag) 32 { 33 if (tree[tree[tree[rt].r].r].sz > tree[tree[rt].l].sz) 34 zag(rt); 35 else if (tree[tree[tree[rt].r].l].sz > tree[tree[rt].l].sz) 36 { 37 zig(tree[rt].r); zag(rt); 38 } 39 else return; 40 } 41 else 42 { 43 if (tree[tree[tree[rt].l].l].sz > tree[tree[rt].r].sz) 44 zig(rt); 45 else if (tree[tree[tree[rt].l].r].sz > tree[tree[rt].r].sz) 46 { 47 zag(tree[rt].l); zig(rt); 48 } 49 else return; 50 } 51 maintain(tree[rt].l,false); 52 maintain(tree[rt].r,true); 53 maintain(rt,false); 54 maintain(rt,true); 55 } 56 inline void insert(int &rt,int k) 57 { 58 if (rt == 0) 59 { 60 rt = ++tot; 61 tree[rt].init(); 62 tree[rt].key = k; 63 } 64 else 65 { 66 tree[rt].sz++; 67 if (k < tree[rt].key) 68 insert(tree[rt].l,k); 69 else insert(tree[rt].r,k); 70 maintain(rt,k>=tree[rt].key); 71 } 72 } 73 inline void del(int &rt,int delay,int min_val) 74 { 75 if (!rt) return; 76 if (tree[rt].key+delay<min_val) 77 { 78 rt = tree[rt].r; 79 del(rt,delay,min_val); 80 } 81 else 82 { 83 del(tree[rt].l,delay,min_val); 84 tree[rt].sz=tree[tree[rt].l].sz+tree[tree[rt].r].sz+1; 85 } 86 87 } 88 inline int kth(int &rt,int k) 89 { 90 int tmp = tree[tree[rt].r].sz + 1; 91 if (tmp == k) 92 return tree[rt].key; 93 else if (tmp < k) 94 return kth(tree[rt].l,k - tmp); 95 return kth(tree[rt].r,k); 96 } 97 int main() 98 { 99 freopen("1503.in","r",stdin); 100 freopen("1503.out","w",stdout); 101 int n,min_val,delay = 0; 102 scanf("%d %d\n",&n,&min_val); 103 int x; 104 char cmd; 105 while (n--) 106 { 107 scanf("%c %d\n",&cmd,&x); 108 if (cmd == 'I') {if (x >= min_val)insert(root,x-delay);} 109 else if (cmd == 'A') delay += x; 110 else if (cmd == 'F') printf("%d\n",tree[root].sz<x?-1:kth(root,x)+delay); 111 else 112 { 113 delay -= x; 114 del(root,delay,min_val); 115 } 116 } 117 printf("%d\n",tot - tree[root].sz); 118 return 0; 119 }
高考结束,重新回归。