zoukankan      html  css  js  c++  java
  • BZOJ 1503 郁闷的出纳员(平衡树)(NOI 2004)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1503

    Description

    OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?

    Input

    Output

    输出文件的行数为F命令的条数加一。对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,如果k大于目前员工的数目,则输出-1。输出文件的最后一行包含一个整数,为离开公司的员工的总数。

    题目大意:略。(原来一进来就滚粗的员工不算入离开公司的员工总数……)

    思路:随便用splay搞搞就好,一条模板题。

    代码(1228MS):

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <map>
      6 using namespace std;
      7 
      8 const int MAXN = 100010;
      9 
     10 int child[MAXN][2], size[MAXN], add[MAXN], wage[MAXN];
     11 int n, minWage, ncnt;
     12 
     13 inline int newNode(int k) {
     14     size[ncnt] = 1;
     15     wage[ncnt] = k;
     16     return ncnt++;
     17 }
     18 
     19 inline void update(int &x) {
     20     size[x] = size[child[x][0]] + size[child[x][1]] + 1;
     21 }
     22 
     23 inline void pushdown(int &x) {
     24     if(add[x]) {
     25         add[child[x][0]] += add[x];
     26         add[child[x][1]] += add[x];
     27         wage[x] += add[x];
     28         add[x] = 0;
     29     }
     30 }
     31 
     32 inline void rotate(int &x, int t) {
     33     int y = child[x][t];
     34     child[x][t] = child[y][t ^ 1];
     35     child[y][t ^ 1] = x;
     36     update(x), update(y);
     37     x = y;
     38 }
     39 
     40 void splay(int &x, int k) {
     41     pushdown(x);
     42     if(k == size[child[x][0]] + 1) return ;
     43     int t = k > size[child[x][0]];
     44     if(t == 1) k -= size[child[x][0]] + 1;
     45     int p = child[x][t];
     46     pushdown(p);
     47     int t2 = k > size[child[p][0]];
     48     int k2 = (t2 == 0 ? k : k - size[child[p][0]] - 1);
     49     if(k != size[child[p][0]] + 1) {
     50         splay(child[p][t2], k2);
     51         if(t == t2) rotate(x, t);
     52         else rotate(child[x][t], t ^ 1);
     53     }
     54     rotate(x, t);
     55 }
     56 
     57 int lower_count(int &x, int val) {
     58     if(x == 0) return 0;
     59     pushdown(x);
     60     if(val <= wage[x]) return lower_count(child[x][0], val);
     61     return size[child[x][0]] + 1 + lower_count(child[x][1], val);
     62 }
     63 
     64 inline int merge(int left, int right) {
     65     splay(left, size[left]);
     66     child[left][1] = right;
     67     update(left);
     68     return left;
     69 }
     70 
     71 inline void split(int x, int k, int &left, int &right) {
     72     splay(x, k);
     73     left = x;
     74     right = child[x][1];
     75     child[x][1] = 0;
     76     update(left);
     77 }
     78 
     79 inline void insert(int &x, int k) {
     80     int t = lower_count(x, k);
     81     if(t > 0) {
     82         int left, right;
     83         split(x, t, left, right);
     84         x = merge(merge(left, newNode(k)), right);
     85     } else x = merge(newNode(k), x);
     86 }
     87 
     88 int main() {
     89     scanf("%d%d", &n, &minWage);
     90     int root = 0, ans = 0;
     91     ncnt = 1;
     92     for(int i = 0; i < n; ++i) {
     93         char c;
     94         int k;
     95         scanf(" %c%d", &c, &k);
     96         if(c == 'I') {
     97             if(k >= minWage) {
     98                 if(root == 0) root = newNode(k);
     99                 else insert(root, k);
    100             } //else ++ans;
    101         };
    102         if(c == 'A') {
    103             add[root] += k;
    104         };
    105         if(c == 'S') {
    106             add[root] -= k;
    107             int t = lower_count(root, minWage);
    108             if(t > 0) {
    109                 int left, right;
    110                 split(root, t, left, right);
    111                 ans += size[left];
    112                 root = right;
    113             }
    114         };
    115         if(c == 'F') {
    116             if(k > size[root]) puts("-1");
    117             else {
    118                 splay(root, size[root] - k + 1);
    119                 printf("%d
    ", wage[root]);
    120             }
    121         };
    122     }
    123     printf("%d
    ", ans);
    124 }
    View Code
  • 相关阅读:
    46 Simple Python Exercises-Higher order functions and list comprehensions
    IDEA一些设置
    DDD建模案例----“视频课程”场景
    LA 4727
    uva 1377
    uva 1421
    UVA
    LA 4731
    uva 11404
    uva 11143
  • 原文地址:https://www.cnblogs.com/oyking/p/3456330.html
Copyright © 2011-2022 走看看