zoukankan      html  css  js  c++  java
  • [BZOJ1503][NOI2004]郁闷的出纳员 无旋Treap

    1503: [NOI2004]郁闷的出纳员

    Time Limit: 5 Sec  Memory Limit: 64 MB

    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

    题解:

    当时想拿这道题学splay的结果把自己调死了……今天又回来看这道题感觉很清晰……

    我们考虑对于一个节点,在它插入以前,工资调整它不会受到影响,插入以后才被影响

    但是我们又不能实时的更新每个节点的值,所以我们考虑用一个变量来差分:

    用tmp变量记录到目前为止的工资变动,如果我们要插入一个本来值为val的节点,我们就插入一个值val-tmp

    而查询的时候,节点的实际值是val+tmp'。tmp'-tmp就是它从插入开始到现在的变化工资,所以这样我们就可以正确的计算了。

    剩下的实现就很简单了,代码见下:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <ctime>
     4 #include <iostream>
     5 #include <cstdlib>
     6 using namespace std;
     7 int minn,ans;
     8 struct Treap
     9 {
    10     Treap *ch[2];
    11     int size,val,key;
    12     Treap(){val=size=0;key=rand();ch[1]=ch[0]=NULL;}
    13     inline void update()
    14         {size=ch[0]->size+ch[1]->size+1;}
    15 }*null=new Treap,*root=null;
    16 typedef pair<Treap*,Treap*> D;
    17 inline Treap* newTreap(int v)
    18 {
    19     Treap *o=new Treap();
    20     o->ch[0]=o->ch[1]=null;
    21     o->size=1;o->val=v;
    22     return o;
    23 }
    24 Treap* merge(Treap* a,Treap* b)
    25 {
    26     if(a==null)return b;
    27     if(b==null)return a;
    28     if(a->key < b->key)
    29         {a->ch[1]=merge(a->ch[1],b);a->update();return a;}
    30     else
    31         {b->ch[0]=merge(a,b->ch[0]);b->update();return b;}
    32 }
    33 D split(Treap *o,int k)
    34 {
    35     if(o==null)return D(null,null);
    36     D y;
    37     if(o->ch[0]->size >= k)
    38         {y=split(o->ch[0],k);o->ch[0]=y.second;o->update();y.second=o;}
    39     else
    40         {y=split(o->ch[1],k-o->ch[0]->size-1);o->ch[1]=y.first;o->update();y.first=o;}
    41     return y;
    42 }
    43 int getrank(Treap *o,int val)
    44 {
    45     if(o==null)return 0;
    46     return o->val >= val?getrank(o->ch[0],val):getrank(o->ch[1],val)+o->ch[0]->size+1;
    47 }
    48 inline int getval(int rank)
    49 {
    50     D x=split(root,rank-1);
    51     D y=split(x.second,1);
    52     int ans=y.first->val;
    53     root=merge(merge(x.first,y.first),y.second);
    54     return ans;
    55 }
    56 inline void insert(int val)
    57 {
    58     int k=getrank(root,val);
    59     D x=split(root,k);
    60     Treap *o=newTreap(val);
    61     root=merge(merge(x.first,o),x.second);
    62 }
    63 inline void erase()
    64 {
    65     D x=split(root,1);
    66     root=x.second;ans++;
    67 }
    68 int main()
    69 {
    70     int m,x,tmp=0;char s[5];
    71     scanf("%d%d",&m,&minn);
    72     while(m--)
    73     {
    74         scanf("%s%d",s,&x);
    75         switch(s[0])
    76         {
    77             case 'I':if(x>=minn)insert(x-tmp);break;
    78             case 'F':
    79             {
    80                 if(root==null||root->size<x)printf("-1
    ");
    81                 else printf("%d
    ",getval(root->size-x+1)+tmp);
    82                 break;
    83             }
    84             case 'A':tmp+=x;break;
    85             case 'S':
    86                 {tmp-=x;while(root!=null&&getval(1)+tmp<minn)erase();break;}
    87         }
    88     }
    89     printf("%d",ans);
    90 }
  • 相关阅读:
    Keras如何构造简单的CNN网络
    到底该如何入门Keras、Theano呢?(浅谈)
    PyCharm使用技巧记录(一)如何查看变量
    使用 环境变量 来配置批量配置apache
    QT静态链接
    NTP服务器
    debian添加sudo
    龙芯8089_D安装debian 8 iessie
    verilog 双向IO实现
    FPGA入门学习第一课:二分频器
  • 原文地址:https://www.cnblogs.com/LadyLex/p/7183447.html
Copyright © 2011-2022 走看看