zoukankan      html  css  js  c++  java
  • BZOJ1503: [NOI2004]郁闷的出纳员(Splay)

    Description

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

    Input

    第一行有两个非负整数n和min。n表示下面有多少条命令,min表示工资下界。
    接下来的n行,每行表示一条命令。命令可以是以下四种之一:
    名称 格式 作用
    I命令 I_k 新建一个工资档案,初始工资为k。
                    如果某员工的初始工资低于工资下界,他将立刻离开公司。
    A命令 A_k 把每位员工的工资加上k
    S命令 S_k 把每位员工的工资扣除k
    F命令 F_k 查询第k多的工资
    _(下划线)表示一个空格,I命令、A命令、S命令中的k是一个非负整数,F命令中的k是一个正整数。
    在初始时,可以认为公司里一个员工也没有。
    I命令的条数不超过100000 
    A命令和S命令的总条数不超过100 
    F命令的条数不超过100000 
    每次工资调整的调整量不超过1000 
    新员工的工资不超过100000

    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

    解题思路:

    splay,维护懒惰标记。

    splay支持删除子树,是比treap优秀的关键。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define lll tr[spc].ch[0]
      6 #define rrr tr[spc].ch[1]
      7 #define ls ch[0]
      8 #define rs ch[1]
      9 #define rrl tr[tr[root].rs].ls
     10 typedef long long lnt;
     11 struct trnt{
     12     int ch[2];
     13     int fa;
     14     lnt lzt;
     15     lnt val;
     16     int wgt;
     17     int num;
     18 }tr[1000000],str;
     19 int sta,fin;
     20 int root;
     21 int n;
     22 lnt m;
     23 int top;
     24 int siz=2;
     25 char cmd[1000];
     26 int bin[1000000];
     27 bool whc(int spc)
     28 {
     29     return tr[tr[spc].fa].rs==spc;
     30 }
     31 int del(int &spc)
     32 {
     33     bin[++top]=spc;
     34     int ans=tr[spc].wgt;
     35     spc=0;
     36     return ans;
     37 }
     38 int newp(void)
     39 {
     40     if(top)
     41     {
     42         int spc=bin[top--];
     43         if(lll)
     44             del(lll);
     45         if(rrr)
     46             del(rrr);
     47         tr[spc]=str;
     48         return spc;
     49     }
     50     return ++siz;
     51 }
     52 void pushup(int spc)
     53 {
     54     tr[spc].wgt=tr[spc].num;
     55     if(lll)
     56         tr[spc].wgt+=tr[lll].wgt;
     57     if(rrr)
     58         tr[spc].wgt+=tr[rrr].wgt;
     59     return ;
     60 }
     61 void add(int spc,lnt v)
     62 {
     63     if(!spc)
     64         return ;
     65     tr[spc].val+=v;
     66     tr[spc].lzt+=v;
     67     return ;
     68 }
     69 void pushdown(int spc)
     70 {
     71     if(!spc)
     72         return ;
     73     if(tr[spc].lzt)
     74     {
     75         add(lll,tr[spc].lzt);
     76         add(rrr,tr[spc].lzt);
     77         tr[spc].lzt=0;
     78     }
     79     return ;
     80 }
     81 void recal(int spc)
     82 {
     83     if(tr[spc].fa)
     84         recal(tr[spc].fa);
     85     pushdown(spc);
     86     return ;
     87 }
     88 void rotate(int spc)
     89 {
     90     int f=tr[spc].fa;
     91     bool k=whc(spc);
     92     tr[f].ch[k]=tr[spc].ch[!k];
     93     tr[spc].ch[!k]=f;
     94     tr[tr[f].fa].ch[whc(f)]=spc;
     95     tr[spc].fa=tr[f].fa;
     96     tr[f].fa=spc;
     97     tr[tr[f].ch[k]].fa=f;
     98     pushup(f);
     99     pushup(spc);
    100     return ;
    101 }
    102 void splay(int spc,int f)
    103 {
    104     recal(spc);
    105     while(tr[spc].fa!=f)
    106     {
    107         int ft=tr[spc].fa;
    108         if(tr[ft].fa==f)
    109         {
    110             rotate(spc);
    111             break;
    112         }
    113         if(whc(spc)^whc(ft))
    114             rotate(spc);
    115         else
    116             rotate(ft);
    117         rotate(spc);
    118     }
    119     if(!f)
    120         root=spc;
    121     return ;
    122 }
    123 int ansp;
    124 void kth(int spc,int k)
    125 {
    126     if(!spc)
    127     {
    128         ansp=-1;
    129         return ;
    130     }
    131     pushdown(spc);
    132     if(tr[rrr].wgt>=k)
    133         return kth(rrr,k);
    134     if(tr[rrr].wgt+tr[spc].num>=k)
    135     {
    136         ansp=spc;
    137         return ;
    138     }
    139     return kth(lll,k-tr[spc].num-tr[rrr].wgt);
    140 }
    141 void maxmin(int spc,lnt v)
    142 {
    143     if(!spc)
    144         return ;
    145     pushdown(spc);
    146     if(tr[spc].val<v)
    147     {
    148         ansp=spc;
    149         return maxmin(rrr,v);
    150     }
    151     return maxmin(lll,v);
    152 }
    153 void minmax(int spc,lnt v)
    154 {
    155     if(!spc)
    156         return ;
    157     pushdown(spc);
    158     if(tr[spc].val>v)
    159     {
    160         ansp=spc;
    161         return minmax(lll,v);
    162     }
    163     return minmax(rrr,v);
    164 }
    165 int main()
    166 {
    167     
    168     scanf("%d%lld",&n,&m);
    169     root=1;
    170     sta=1;
    171     fin=2;
    172     tr[1]=(trnt){{0,2},0,0,-0x3f3f3f3f3f3f3f3fll,0,0};
    173     tr[2]=(trnt){{0,0},1,0,0x3f3f3f3f3f3f3f3fll,0,0};
    174     int ans=0;
    175     while(n--)
    176     {
    177         lnt x;
    178         scanf("%s",cmd+1);
    179         scanf("%lld",&x);
    180         if(cmd[1]=='I')
    181         {
    182             if(x<m)
    183                 continue;
    184             maxmin(root,x);
    185             splay(ansp,0);
    186             minmax(root,x);
    187             splay(ansp,root);
    188             if(rrl)
    189             {
    190                 tr[rrl].num++;
    191             }else{
    192                 rrl=newp();
    193                 tr[rrl]=(trnt){{0,0},tr[root].rs,0,x,1,1};
    194             }
    195             pushup(rrl);
    196             pushup(tr[root].rs);
    197             pushup(root);
    198         }else if(cmd[1]=='A')
    199         {
    200             if(!x)
    201                 continue;
    202             splay(sta,0);
    203             splay(fin,root);
    204             add(rrl,x);
    205         }else if(cmd[1]=='S')
    206         {
    207             splay(sta,0);
    208             splay(fin,root);
    209             ansp=-1;
    210             add(rrl,-x);
    211             minmax(rrl,m-1);
    212             if(ansp==-1)
    213                 continue;
    214             splay(sta,0);
    215             splay(ansp,root);
    216             if(!rrl)
    217                 continue;
    218             ans+=del(rrl);
    219             pushup(tr[root].rs);
    220             pushup(root);
    221         }else{
    222             splay(sta,0);
    223             splay(fin,root);
    224             kth(rrl,x);
    225             if(ansp==-1)
    226                 printf("%d
    ",-1);
    227             else
    228                 printf("%lld
    ",tr[ansp].val);
    229         }
    230         splay(sta,0);
    231         splay(fin,root);
    232         ansp=-1;
    233         minmax(rrl,m-1);
    234         if(ansp==-1)
    235             continue;
    236         splay(sta,0);
    237         splay(ansp,root);
    238         if(!rrl)
    239             continue;
    240         ans+=del(rrl);
    241         pushup(tr[root].rs);
    242         pushup(root);
    243     }
    244     printf("%d
    ",ans);
    245     return 0;
    246 }
  • 相关阅读:
    Java Spring Boot VS .NetCore (十) Java Interceptor vs .NetCore Interceptor
    Java Spring Boot VS .NetCore (九) Spring Security vs .NetCore Security
    IdentityServer4 And AspNetCore.Identity Get AccessToken 问题
    Java Spring Boot VS .NetCore (八) Java 注解 vs .NetCore Attribute
    Java Spring Boot VS .NetCore (七) 配置文件
    Java Spring Boot VS .NetCore (六) UI thymeleaf vs cshtml
    Java Spring Boot VS .NetCore (五)MyBatis vs EFCore
    Java Spring Boot VS .NetCore (四)数据库操作 Spring Data JPA vs EFCore
    Java Spring Boot VS .NetCore (三)Ioc容器处理
    Java Spring Boot VS .NetCore (二)实现一个过滤器Filter
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9726368.html
Copyright © 2011-2022 走看看