zoukankan      html  css  js  c++  java
  • luogu P2048 [NOI2010]超级钢琴

    传送门

    编号好评

    先把所有数记个前缀和,然后对于某一个右端点(r(rgeq L)),能计入答案的(l)的范围为([max(r-R,0),r-L])

    可以开一个大根堆,先对于所有右端点(r),加入(pre_r-min(pre_{l})),然后每次取出堆顶加入答案,弹掉堆顶,同时如果这是堆顶对应右端点减第(k)小的左端点的值,就把右端点减第(k+1)小的左端点的值加入堆中,这里我们可以使用主席树查询该区间内的任意第(k)小值

    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define db double
    #define eps (1e-7)
    
    using namespace std;
    const int N=500000+10;
    const LL inf=1ll<<45;
    il LL rd()
    {
      re LL x=0,w=1;re char ch=0;
      while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
      while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
      return x*w;
    }
    
    #define mid ((l+r)>>1)
    
    int s[N*20],ch[N*20][2],rt[N],tt;
    int n,kk,L,R,a[N],b[N],pp[N][3];
    il void inst(int p)
    {
      rt[p]=++tt;
      int o1=rt[p],o2=rt[p-1],l=1,r=n;
      s[o1]=s[o2]+1;
      while(l<r)
        {
          if(a[p]<=mid)
            {
              ch[o1][0]=++tt,ch[o1][1]=ch[o2][1];
              o1=ch[o1][0],o2=ch[o2][0],r=mid;
            }
          else
            {
              ch[o1][0]=ch[o2][0],ch[o1][1]=++tt;
              o1=ch[o1][1],o2=ch[o2][1],l=mid+1;
            }
          s[o1]=s[o2]+1;
        }
    }
    int quer(int o1,int o2,int l,int r,int k)
    {
      if(l==r) return b[l];
      int kkk=s[ch[o1][0]]-s[ch[o2][0]];
      if(k<=kkk) return quer(ch[o1][0],ch[o2][0],l,mid,k);
      else return quer(ch[o1][1],ch[o2][1],mid+1,r,k-kkk);
    }
    struct node
    {
      LL x;
      int n;
      node(){x=-inf;}
    }hp[N*3];
    LL ans;
    int tp;
    il void ps(node a)
    {
      hp[++tp]=a;
      int nw=tp;
      while(nw>1&&hp[nw].x>hp[nw>>1].x) swap(hp[nw],hp[nw>>1]),nw>>=1;
    }
    il void po()
    {
      hp[1]=hp[tp],hp[tp--].x=-inf;
      int nw=1,p=2;
      while(hp[p].x>-inf)
        {
          if(hp[p+1].x>hp[p].x) ++p;
          if(hp[nw].x>hp[p].x) break;
          swap(hp[nw],hp[p]);
          nw=p,p<<=1;
        }
    }
    int q;
    
    int main()
    {
      n=rd()+1,kk=rd(),L=rd(),R=rd();
      for(int i=2;i<=n;i++) a[i]=b[i]=a[i-1]+rd();
      sort(b+1,b+n+1),unique(b+1,b+n+1);
      int nn=1;
      while(b[nn]<b[nn+1]) ++nn;
      for(int i=1;i<=n;i++)
        {
          a[i]=lower_bound(b+1,b+nn+1,a[i])-b;
          inst(i);
        }
      for(int i=L+1;i<=n;i++)
        {
          pp[i][0]=max(1,i-R),pp[i][1]=i-L,pp[i][2]=1;
          node xx;
          xx.x=(LL)(b[a[i]]-quer(rt[pp[i][1]],rt[pp[i][0]-1],1,n,pp[i][2])),xx.n=i;
          ps(xx);
        }
      for(int h=1;h<=kk;h++)
        {
          ans+=hp[1].x;
          int i=hp[1].n;
          po();
          ++pp[i][2];
          if(pp[i][2]>pp[i][1]-pp[i][0]+1) continue;
          node xx;
          xx.x=b[a[i]]-quer(rt[pp[i][1]],rt[pp[i][0]-1],1,n,pp[i][2]),xx.n=i;
          ps(xx);
        }
      printf("%lld
    ",ans);
      return 0;
    }
    
    
  • 相关阅读:
    Django
    索引
    idea启动tomcat后控制台日志显示中文乱码问题
    Elasticsearch
    Hive 开窗函数
    hadoop-3.1.1集群搭建
    hadoop-2.6.5集群搭建
    spark集群搭建(spark版本2.3.2)
    Zookeeper
    spark-submit(spark版本2.3.2)
  • 原文地址:https://www.cnblogs.com/smyjr/p/9739244.html
Copyright © 2011-2022 走看看