• BZOJ3461 : Jry的时间表


    fl[i]表示[1,i]操作一次,且在[j+1,i]处操作的最大值

    1:把[j+1,i]改为b[i]:

      max(sum[j]+b[i]*(i-j))

    =b[i]*i+max(-j*b[i]+sum[j])(0<=j<i)

    由于j递增,-j递减,所以从右往左建立凸壳,查询时在凸壳上二分查找即可,时间复杂度$O(nlog n)$。

    2:把[j+1,i]改为b[j]:

      max(sum[j]+b[j+1]*(i-j))

    =max(b[j+1]*i+sum[j]-b[j+1]*j)(0<=j<i)

    考虑分治,对[l,mid]按b[j+1]从小到大排序,然后斜率优化即可,时间复杂度$O(nlog^2n)$。

    将a,b序列翻转,即可求出fr[i]。

    ans=max(fl[i]-sum[i]+fr[j]+sum[j-1])(0<=i<j<=n)

         =max(fr[j]+sum[j-1]+max(fl[i]-sum[i]))

    维护前缀最大的fl[i]-sum[i]即可。

    #include<cstdio>
    #include<algorithm>
    #define N 500010
    typedef long long ll;
    int n,i,j,a[N],b[N],c[N],e[N],q[N],h,t;ll sum[N],d[N],f[N],fl[N],fr[N],pre,ans;
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline double pos(int x,int y){return (double)(sum[x]-sum[y])/(double)(x-y);}
    inline ll ask(int x){
      int l=1,r=t-1,fin=t,mid;
      while(l<=r){
        mid=(l+r)>>1;
        if((double)x>pos(q[mid],q[mid+1]))r=(fin=mid)-1;else l=mid+1;
      }
      return sum[q[fin]]-(ll)q[fin]*x;
    }
    inline void up(ll&x,ll y){if(x<y)x=y;}
    inline bool cmp(int x,int y){return c[x]==c[y]?d[x]>d[y]:c[x]<c[y];}
    inline double slope(int x,int y){return (double)(d[x]-d[y])/(double)(c[y]-c[x]);}
    void solve(int l,int r){
      if(l==r)return;
      int mid=(l+r)>>1;
      solve(l,mid),solve(mid+1,r);
      for(j=0,i=l;i<=mid;i++)e[j++]=i;
      for(std::sort(e,e+j,cmp),t=i=0,h=1;i<j;i++){
        if(i&&c[e[i]]==c[e[i-1]])continue;
        while(t>1&&slope(q[t-1],q[t])>=slope(q[t],e[i]))t--;
        q[++t]=e[i];
      }
      for(i=mid+1;i<=r;i++){
        while(h<t&&(d[q[h]]-d[q[h+1]])<=(ll)i*(c[q[h+1]]-c[q[h]]))h++;
        up(f[i],(ll)c[q[h]]*i+d[q[h]]);
      }
    }
    void work(){
      for(i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
      for(t=i=0;i<=n;q[++t]=i++){
        if(i)f[i]=(ll)b[i]*i+ask(b[i]);
        while(t>1&&pos(i,q[t])>pos(q[t],q[t-1]))t--;
      }
      for(i=0;i<n;i++)c[i]=b[i+1],d[i]=sum[i]-(ll)b[i+1]*i;
      solve(0,n);
    }
    int main(){
      for(read(n),i=1;i<=n;i++)read(a[i]);
      for(i=1;i<=n;i++)read(b[i]);
      work();
      for(i=1;i<=n;i++)fl[i]=f[i];
      for(i=1,j=n;i<j;i++,j--)t=a[i],a[i]=a[j],a[j]=t,t=b[i],b[i]=b[j],b[j]=t;
      work();
      for(i=1;i<=n;i++)fr[n-i+1]=f[i];
      for(i=1;i<=n;i++)sum[i]=sum[i-1]+a[n-i+1];
      for(ans=sum[n],i=1;i<=n;i++){
        up(ans,fr[i]+sum[i-1]+pre);
        up(pre,fl[i]-sum[i]);
      }
      return printf("%lld",ans),0;
    }
    

      

  • 相关阅读:
    java字节中的基本类型的职业的数目 (采访总是问)
    hdu 1814 Peaceful Commission (2-sat 输出字典序最小的路径)
    Ubuntu Server 14.04 LTS(64bit)已安装 weblogic Server 12c(12.1.3) Zip Distribution
    Tyvj P1015 公路骑 (DP)
    编程算法
    POJ 2502 Subway (Dijkstra 最短+建设规划)
    android_Activity生命周期功能
    ftk学习记录(脚本文章)
    2013年周二
    2013年第32周星期1
  • 原文地址:https://www.cnblogs.com/clrs97/p/4620687.html
Copyright © 2020-2023  润新知