zoukankan      html  css  js  c++  java
  • 【权值分块】bzoj1503 [NOI2004]郁闷的出纳员

    权值分块,离散化非常蛋疼,只能离散化搞……

    需要支持操作:删除<=某个值得所有权值==打标记 O(sqrt(n))

    码长和我的平衡树差不多……速度快3倍左右。

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 #define N 201001
      7 struct Point{int v,p;}tmp[N];
      8 bool operator < (const Point &a,const Point &b){return a.v<b.v;}
      9 int n,m,Infu,a[N],c[N],leave,
     10 en/*插入的权值数*/,en2/*离散化之后的权值种类数*/,ma[N];
     11 char op[N];
     12 int num[N],l[460],CH[12],r[460],Num,sumv[460],sum,sz,b[N],all;
     13 bool delta[N];
     14 inline void R(int &x){
     15     char c=0;int f=1;
     16     for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
     17     for(x=0;c>='0'&&c<='9';c=getchar())(x*=10)+=(c-'0');
     18     x*=f;
     19 }
     20 inline void P(int x)
     21 {
     22     if(!x){putchar('0');puts("");return;}
     23     if(x<0){putchar('-');x=-x;}Num=0;
     24     while(x>0)CH[++Num]=x%10,x/=10;
     25     while(Num)putchar(CH[Num--]+48);puts("");
     26 }
     27 void makeblock()
     28 {
     29     sz=sqrt(en2); if(!sz) sz=1;
     30     for(sum=1;sum*sz<en2;sum++)
     31       {
     32           l[sum]=r[sum-1]+1;
     33           r[sum]=sum*sz;
     34           for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
     35       }
     36     l[sum]=r[sum-1]+1;
     37     r[sum]=en2;
     38     for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
     39 }
     40 void pushdown(const int &p)
     41 {
     42     if(delta[p])
     43       {
     44           for(int i=l[p];i<=r[p];i++) b[i]=0;
     45           delta[p]=0;
     46       }
     47 }
     48 inline void Insert(const int &x){pushdown(num[x]); b[x]++; sumv[num[x]]++; all++;}
     49 inline void Delete(const int &v)//删除小于等于v的所有权值 
     50 {
     51     int used=all; pushdown(num[v]);
     52     for(int i=v;i>=l[num[v]];i--)
     53       {
     54           sumv[num[i]]-=b[i];
     55           all-=b[i];
     56           b[i]=0;
     57       }
     58     for(int i=num[v]-1;i>=1;i--) if(sumv[i])
     59       {
     60           delta[i]=1;
     61           all-=sumv[i];
     62           sumv[i]=0;
     63       } leave+=(used-all);
     64 }
     65 inline int Kth(const int &x)
     66 {
     67     int cnt=0;
     68     for(int i=sum;;i--)
     69       {
     70         cnt+=sumv[i];
     71         if(cnt>=x)
     72           {
     73             cnt-=sumv[i];
     74             for(int j=r[i];;j--)
     75             {cnt+=b[j]; if(cnt>=x) return j;}
     76           }
     77       }
     78 }
     79 int main()
     80 {
     81     R(n); R(m);
     82     for(int i=1;i<=n;i++)
     83       {
     84           op[i]=getchar(); R(a[i]);
     85           if(op[i]=='I')
     86             {
     87                 tmp[++en].v=a[i]-Infu;//为新员工消除之前工资变化的影响 
     88                 tmp[en].p=en;
     89             }
     90           else if(op[i]=='A') Infu+=a[i];
     91           else if(op[i]=='S')
     92           {
     93               Infu-=a[i];
     94               tmp[++en].v=m-Infu-1;//每次删除<=m-Infu-1的权值 
     95               tmp[en].p=en;
     96           }
     97       }
     98     sort(tmp+1,tmp+en+1);
     99     ma[c[tmp[1].p]=++en2]=tmp[1].v;
    100     for(int i=2;i<=en;i++)
    101       {
    102           if(tmp[i].v!=tmp[i-1].v) en2++;
    103           ma[c[tmp[i].p]=en2]=tmp[i].v;
    104       } Infu=en=0; makeblock();
    105     for(int i=1;i<=n;i++)
    106       {
    107           if(op[i]=='I') {en++; if(a[i]>=m) Insert(c[en]);}
    108           else if(op[i]=='A') Infu+=a[i];
    109           else if(op[i]=='S')
    110           {
    111             Infu-=a[i];
    112             Delete(c[++en]);
    113           }
    114           else
    115             {
    116                 if(a[i]>all) puts("-1");
    117                 else P(ma[Kth(a[i])]+Infu);
    118             }
    119       } P(leave);
    120     return 0;
    121 }
  • 相关阅读:
    PHP5.4中新增的traits
    PHP各版本的区别
    冒泡排序原理
    服务器&linux
    PHP
    excel 导出
    try cache
    sql
    Linux下php安装Redis扩展
    Redis安装部署
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4107496.html
Copyright © 2011-2022 走看看