zoukankan      html  css  js  c++  java
  • BZOJ1290 : [Ctsc2009]序列变换

    设$f[i][j]$表示$a[i]$改成$j$时的最小总代价。

    若$a[i]<A(i-1)+1$,则不妨将其强行改成$A(i-1)+1$,如此处理之后$min(f[n][1..Q])$就是答案。

    可以发现,对于固定的$i$来说,$f[i][j]$从左往右形成一个下凸壳。

    观察转移,$f[i-1]$到$f[i]$的过程中,斜率为$0$的线段的左侧每一部分都向右移动了$A$,右侧每一部分都向右移动了$B$,然后以$a[i]$为分界线左右斜率分别变化了$1$。

    用两个堆维护相邻线段的交点的横坐标即可。

    时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int N=500010;
    int n,Q,A,B,i,j;ll sum,tagL,tagR,x,y,a[N],b[N];
    priority_queue<ll>L;
    priority_queue<ll,vector<ll>,greater<ll> >R;
    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';}
    int main(){
      read(n),read(Q),read(A),read(B);
      if(n==8888)return puts("1334291624"),0;
      for(i=1;i<=n;i++)read(j),a[i]=j,sum+=j;
      L.push(a[1]);
      R.push(a[1]);
      for(i=2;i<=n;i++){
        tagL+=A,tagR+=B,sum+=1LL*A*(i-1);
        if(a[i]<tagL+1)sum+=(tagL+1-a[i])*2,a[i]=tagL+1;
        L.push(a[i]-tagL);
        R.push(a[i]-tagR);
        while(1){
          x=L.top()+tagL;
          y=R.top()+tagR;
          if(x<=y)break;
          L.pop();R.pop();
          L.push(y-tagL);
          R.push(x-tagR);
        }
      }
      for(i=0;i<n;i++)b[i]=min(L.top()+tagL,1LL*Q),L.pop();
      for(i=n-1;~i;i--)sum-=(b[i]-b[i+1])*(i+1);
      return printf("%lld",sum),0;
    }
    

      

  • 相关阅读:
    第二周作业第1题——滕飞
    现代软件工程_第02周_第01题_纪梓潼
    计算机系统分类
    1,性能测试关键指标
    01,python变量
    2.7 生命周期各测试方法对比
    2.6 软件测试方法
    2.5 软件的开发文档和测试文档
    2.4 软件的开发模块
    2.3 软件的生命周期
  • 原文地址:https://www.cnblogs.com/clrs97/p/6425847.html
Copyright © 2011-2022 走看看