zoukankan      html  css  js  c++  java
  • BZOJ3024 : [Balkan2012]balls

    问题1:

    ans=max(sum[n]-(sum[i]-sum[j-1])+a[i]*(i-j+1))

    =max(sum[n]-sum[i]+sum[j-1]+a[i]*(i+1)-a[i]*j)

    =sum[n]-sum[i]+a[i]*(i+1)+f[i]

    f[i]=max(-j*a[i]+sum[j-1]),j<i

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

    问题2:

    将序列翻转后即化为问题1。

    #include<cstdio>
    #define N 300010
    typedef long long ll;
    int n,i,j,a[N],q[N],t;ll sum[N],b[N],f[N],ans;
    inline void read(int&a){
      char c;bool f=0;a=0;
      while(!((((c=getchar())>='0')&&(c<='9'))||(c=='-')));
      if(c!='-')a=c-'0';else f=1;
      while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';
      if(f)a=-a;
    }
    inline double pos(int x,int y){return (double)(b[x]-b[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 b[q[fin]]-(ll)q[fin]*x;
    }
    inline void up(ll x){if(ans<x)ans=x;}
    void work(){
      for(ans=-1LL<<60,i=1;i<=n;i++)sum[i]=sum[i-1]+a[i],b[i]=sum[i-1];
      for(t=0,i=1;i<=n;q[++t]=i++){
        if(i>1)up(sum[n]-sum[i]+(ll)a[i]*(i+1)+ask(a[i]));
        while(t>1&&pos(i,q[t])>pos(q[t],q[t-1]))t--;
      }
      printf("%lld
    ",ans);
    }
    int main(){
      for(read(n),i=1;i<=n;i++)read(a[i]);
      work();
      for(i=1,j=n;i<j;i++,j--)t=a[i],a[i]=a[j],a[j]=t;
      work();
      return 0;
    }
    

      

  • 相关阅读:
    jquery选择器
    frameset的target属性
    最长回文子串 南邮NOJ 1100
    最长回文子串 南邮NOJ 1100
    最长回文子串 南邮NOJ 1100
    NOJ 蛇形填数 1094
    NOJ 蛇形填数 1094
    NOJ 蛇形填数 1094
    NOJ 蛇形填数 1094
    开灯问题 南邮NOJ 1589 (另一种解法)
  • 原文地址:https://www.cnblogs.com/clrs97/p/4619850.html
Copyright © 2011-2022 走看看