• 【BZOJ1503】 [NOI2004]郁闷的出纳员 splay


    splay模板题,都快把我做忧郁了。

    由于自己调两个坑点。

    1.删除时及时updata

    2.Kth 考虑k满足该点的条件即r->ch[1]->size+1<=k && r->ch[1]->size+r->num>=k

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 using namespace std;
      5 struct SplayNode
      6 {
      7     SplayNode *fa,*ch[2];
      8     SplayNode();
      9     int data,size,num;
     10     int chr() {return this==fa->ch[1];}
     11     void updata() { size=ch[0]->size+ch[1]->size+num;}
     12 }*null;
     13 SplayNode::SplayNode() {fa=ch[0]=ch[1]=null; num=1; size=0;}
     14 int n,minn;
     15 inline int read() {int ans=0; char c; while ((c=getchar())==' ' || c=='
    ' || c=='
    '); ans=c-'0'; while (isdigit(c=getchar())) ans=ans*10+c-'0'; return ans;}
     16 namespace Splay
     17 {
     18     SplayNode *Root;
     19     void MakeTree()
     20     {
     21         null=new SplayNode;
     22         *null=SplayNode();
     23         Root=null;
     24     }
     25     void rotate(SplayNode *x)
     26     {
     27         SplayNode *r=x->fa;
     28         if (x==null || r==null) return;
     29         int t=x->chr();
     30         r->ch[t]=x->ch[t^1];
     31         r->ch[t]->fa=r;
     32         if (r->fa==null) Root=x;
     33         else r->fa->ch[r->chr()]=x;
     34         x->fa=r->fa;
     35         x->ch[t^1]=r;
     36         r->fa=x;
     37         r->updata();
     38         x->updata();
     39     }
     40     void splay(SplayNode *x,SplayNode *y)
     41     {
     42         for (;x->fa!=y;rotate(x))
     43             if (x->fa->fa!=y)
     44                 if (x->chr()==x->fa->chr()) rotate(x->fa);
     45                 else rotate(x);
     46     }
     47     void insert(int v)
     48     {
     49         SplayNode *r=Root;
     50         if (Root==null)
     51         {
     52             Root=new SplayNode;
     53             Root->data=v;
     54             Root->updata();
     55             return;
     56         }
     57         if (Root->data==v)
     58         {
     59             Root->num++;
     60             Root->updata();
     61             return;
     62         }
     63         while (r->ch[r->data<v]!=null)
     64         {
     65             r=r->ch[r->data<v];
     66             if (r->data==v)
     67             {
     68                 r->num++;
     69                 splay(r,null);
     70                 return;
     71             }
     72         }
     73         r->ch[r->data<v]=new SplayNode;
     74         r->ch[r->data<v]->data=v;
     75         r->ch[r->data<v]->fa=r;
     76         splay(r->ch[r->data<v],null);
     77     }
     78     void pre(SplayNode *x,int v,SplayNode *&ans)
     79     {
     80         if (x==null) return;
     81         else if (x->data<v)
     82         {
     83             if (ans->data<x->data || ans==null) ans=x;
     84             pre(x->ch[1],v,ans);    
     85         }else pre(x->ch[0],v,ans);
     86     }
     87     void suc(SplayNode *x,int v,SplayNode *&ans)
     88     {
     89         if (x==null) return;
     90         else if (x->data>v)
     91         {
     92             if (ans->data>x->data || ans==null) ans=x;
     93             suc(x->ch[0],v,ans);
     94         }else suc(x->ch[1],v,ans);
     95     }
     96     void del(int v)
     97     {
     98         SplayNode *q=null; pre(Root,v,q);
     99         SplayNode *p=null; suc(Root,v,p);
    100         if (q==null && p==null)
    101         {
    102             if (Root->num==1) Root=null;
    103             else Root->num--,Root->updata();
    104             return;
    105         }
    106         if (q==null)
    107         {
    108             splay(p,null);
    109             if (p->ch[0]->num==1) p->ch[0]=null,p->updata();
    110             else p->ch[0]->num--,splay(p->ch[0],null);
    111             return;
    112         }
    113         if (p==null)
    114         {
    115             splay(q,null);
    116             if (q->ch[1]->num==1) p->ch[1]=null,p->updata();
    117             else p->ch[1]->num--,splay(p->ch[0],null);
    118             return;
    119         }
    120         splay(q,null);
    121         splay(p,q);
    122         if (p->ch[0]->num==1) p->ch[0]=null,p->updata();
    123         else p->ch[0]->num--,splay(p->ch[0],null);
    124         return;
    125     }
    126     SplayNode *Kth(int k)
    127     {
    128         SplayNode *r=Root;
    129         while (r!=null)
    130         {
    131             if (k<=r->ch[1]->size) r=r->ch[1];
    132             else if (r->ch[1]->size+1<=k && r->ch[1]->size+r->num>=k) return r;
    133             else 
    134             {
    135                 k-=r->ch[1]->size+r->num;
    136                 r=r->ch[0];
    137             }
    138         }
    139         return r;
    140     }
    141     SplayNode *find(int v)
    142     {
    143         SplayNode *r=Root;
    144         while (r!=null)
    145         {
    146             if (r->data==v)
    147             {
    148                 splay(r,null);
    149                 return r;
    150             }
    151             r=r->ch[r->data<v];
    152         }
    153         return null;
    154     }
    155 }
    156 int main()
    157 {
    158     //freopen("1503.out","w",stdout);
    159     int ans=0,dell=0,ans1=0;
    160     Splay::MakeTree();
    161     n=read(); minn=read();
    162     while (n--)
    163     {
    164         char s[6];
    165         int x;
    166         scanf("%s",s); x=read();
    167         if (s[0]=='I') if (x>=minn) Splay::insert(x-dell),ans++;
    168         if (s[0]=='A') dell+=x;
    169         if (s[0]=='S') 
    170         {
    171             dell-=x;
    172             Splay::insert(minn-dell);
    173             SplayNode *r=Splay::find(minn-dell);
    174         //    Splay::splay(r,null);
    175             if   (r->ch[0]!=null) ans1+=r->ch[0]->size,ans-=r->ch[0]->size;
    176             while (r->ch[0]!=null)
    177             {
    178                 Splay::del(r->ch[0]->data);
    179                 Splay::splay(r,null);
    180             }
    181             Splay::del(minn-dell);
    182         }
    183         if (s[0]=='F') 
    184         if (x>ans) puts("-1");
    185         else
    186         printf("%d
    ",Splay::Kth(x)->data+dell);
    187     }
    188     printf("%d
    ",ans1);
    189     return 0;
    190 }
    View Code


    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

     
    —Anime Otaku Save The World.
  • 相关阅读:
    Loadrunner的Tuxedo脚本分析,基本流程和基本函数介绍
    安装ArcGIS Server 9.2的一些建议
    .obj,.lib,.dll,.h之间的相互关系
    中国Albers 投影参数设置参考资料
    投影常识
    vc++2005环境中静态调用DLL(隐式)
    设置GDAL_DATA环境变量
    开源代码搜索利器Koders
    更正GDAL_DATA设置一文错误
    2007年的元宵节
  • 原文地址:https://www.cnblogs.com/DMoon/p/5303623.html
Copyright © 2020-2023  润新知