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

    题目大意:
      给定$n(nleq100000)$和$min$,按照给定的顺序进行以下操作共$n$次:
        1.加入一个数;
        2.把所有数加上$x$;
        3.把所有数减去$x$,并把小于$min$的数删去;
        4.询问第$k$大数。

    思路:
      Splay。区间加减可以用tag实现,删数可以通过把大于等于$min$的最小数提到根,然后删除左子树。

      1 #include<cstdio>
      2 #include<cctype>
      3 #include<climits>
      4 inline int getint() {
      5     register char ch;
      6     while(!isdigit(ch=getchar()));
      7     register int x=ch^'0';
      8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
      9     return x;
     10 }
     11 inline char getalpha() {
     12     register char ch;
     13     while(!isalpha(ch=getchar()));
     14     return ch;
     15 }
     16 const int N=100001;
     17 int ext;
     18 class SplayTree {
     19     private:
     20         int val[N],size[N],tag[N],par[N],ch[N][2],root,cnt;
     21         int sz,new_node(const int &x) {
     22             val[++sz]=x;
     23             size[sz]=1;
     24             return sz;
     25         }
     26         void push_up(const int &p) {
     27             size[p]=size[ch[p][0]]+size[ch[p][1]]+1;
     28         }
     29         void push_down(const int &p) {
     30             if(ch[p][0]) {
     31                 tag[ch[p][0]]+=tag[p];
     32                 val[ch[p][0]]+=tag[p];
     33             }
     34             if(ch[p][1]) {
     35                 tag[ch[p][1]]+=tag[p];
     36                 val[ch[p][1]]+=tag[p];
     37             }
     38             tag[p]=0;
     39         }
     40         void rotate(const int &x) {
     41             const int y=par[x],z=par[y];
     42             const bool b=x==ch[y][0];
     43             push_down(y),push_down(x);
     44             par[ch[x][b]=par[ch[y][!b]=ch[x][b]]=y]=x;
     45             par[ch[z][y==ch[z][1]]=x]=z;
     46             push_up(y),push_up(x);
     47         }
     48         void splay(int x,const int &goal) {
     49             for(register int y=par[x],z=par[y];y!=goal;rotate(x),z=par[y=par[x]]) {
     50                 if(z!=goal) rotate((x==ch[y][0])^(y==ch[z][0])?x:y);
     51             }
     52             if(!goal) root=x;
     53         }
     54     public:
     55         SplayTree() {
     56             root=ch[0][1]=new_node(INT_MAX>>1);
     57         }
     58         void insert(const int &x) {
     59             int y=root;
     60             while(ch[y][x>val[y]]) {
     61                 push_down(y);
     62                 y=ch[y][x>val[y]];
     63             }
     64             push_down(y);
     65             par[ch[y][x>val[y]]=new_node(x)]=y;
     66             splay(y,0);
     67             cnt++;
     68         }
     69         void modify(const int &x) {
     70             tag[root]+=x;
     71             val[root]+=x;
     72         }
     73         void erase(const int &min) {
     74             int tmp=0;
     75             for(register int y=root;y;y=ch[y][min>val[y]]) {
     76                 push_down(y);
     77                 if(val[y]>=min) tmp=y;
     78             }
     79             if(!tmp) return;
     80             splay(tmp,0);
     81             if(!ch[tmp][0]) return;
     82             ext+=size[ch[tmp][0]];
     83             size[tmp]-=size[ch[tmp][0]];
     84             cnt-=size[ch[tmp][0]];
     85             ch[tmp][0]=0;
     86         }
     87         int find(int x) {
     88             if(x>cnt) return -1;
     89             for(register int y=root;;y=ch[y][size[ch[y][1]]>x]) {
     90                 push_down(y);
     91                 if(par[y]&&y==ch[par[y]][0]) x-=size[ch[par[y]][1]]+1;
     92                 if(size[ch[y][1]]==x) return val[y];
     93             }
     94         }
     95 };
     96 SplayTree t;
     97 int main() {
     98     for(register int i=getint(),min=getint();i;i--) {
     99         const char opt=getalpha();
    100         const int x=getint();
    101         if(opt=='I') {
    102             if(x>=min) t.insert(x);
    103         }
    104         if(opt=='A') t.modify(x);
    105         if(opt=='S') {
    106             t.modify(-x);
    107             t.erase(min);
    108         }
    109         if(opt=='F') printf("%d
    ",t.find(x));
    110     }
    111     printf("%d
    ",ext);
    112     return 0;
    113 }
  • 相关阅读:
    C#下载文件代码更新20070920
    判断IP地址是否合法的sql2000使用存储过程跟函数
    百万级SQL分页存储过程
    C#批量重命名文件代码的实现
    单个分页的存储过程
    阿江网站访问统计系统设计构思分析
    c#查询QQ状态是否在线查询代码
    C# public class Person
    C#禁止应用程序的多重运行
    Outlook最小化到托盘的设置方法
  • 原文地址:https://www.cnblogs.com/skylee03/p/8512889.html
Copyright © 2011-2022 走看看