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

Sample Output

10
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 }
View Code

 

posted @ 2015-02-16 20:14  lmxyy  阅读(156)  评论(0编辑  收藏  举报