BZOJ 2726: [SDOI2012]任务安排 斜率优化 + 凸壳二分 + 卡精

Code: 

#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin)  
#define maxn 1000000 
#define ll long long 
#define ldb long double 
using namespace std; 
int n,s,head,tail; 
int q[maxn]; 
ll f[maxn],sumt[maxn],sumf[maxn]; 
ldb x(int i) { return (ldb)1.000000*sumf[i]; }
ldb y(int i) { return (ldb)1.000000*f[i]; }
ldb slope(int i,int j) { return (ldb)(y(i)-y(j))/(ldb)(x(i)-x(j)); }
int main()
{ 
    int i,j; 
    // setIO("input");  
    scanf("%d%d",&n,&s);
    for(i=1;i<=n;++i) 
    {
        scanf("%lld%lld",&sumt[i],&sumf[i]);                    
        sumt[i]+=sumt[i-1]; 
        sumf[i]+=sumf[i-1]; 
    } 
    for(i=1;i<=n;++i) 
    {
        int l=1,r=tail,re=0; 
        while(l<=r) 
        {
            int mid=(l+r)>>1;   
            if(f[q[mid]]-f[q[mid-1]] < (sumt[i]+s)*(sumf[q[mid]]-sumf[q[mid-1]]))
                re=mid,l=mid+1;   
            // if(slope(q[mid], q[mid-1])<sumt[i]+s)     
            else r=mid-1; 
        }
        f[i]=f[q[re]]-(sumt[i]+s)*(sumf[q[re]])+sumf[i]*sumt[i]+s*sumf[n]; 
        while(tail&&(f[q[tail]]-f[i])*(sumf[q[tail-1]]-sumf[i])<=(f[q[tail-1]]-f[i])*(sumf[q[tail]]-sumf[i]))--tail;  
        q[++tail]=i;              
    }
    printf("%lld\n",f[n]); 
    return 0;   
}

  

posted @ 2019-07-06 09:57  EM-LGH  阅读(167)  评论(0编辑  收藏  举报