任务安排3

题目传送门

考虑这里的斜率 \(t_i+s\) 并不单调,所以用二分解决。

#include<bits/stdc++.h>
using namespace std;
#define L(i,l,r) for(int i=l;i<=r;++i)
#define R(i,l,r) for(int i=r;i>=l;--i)
const int N=300010;
int n,s,c[N],t[N],hh,tt,q[N];
typedef long long ll;
ll f[N];
int main(){
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    // ios::sync_with_stdio(0);
    // cin.tie(0);
    // cout.tie(0);
    scanf("%d%d",&n,&s);
    L(i, 1, n){
        scanf("%d%d",t+i,c+i);
        t[i]+=t[i-1];
        c[i]+=c[i-1];
    }
    L(i, 1, n){
        int l=hh,r=tt;
        while(l<r){
            int mid=(l+r)>>1;
            if((f[q[mid+1]]-f[q[mid]])>1ll*(s+t[i])*(c[q[mid+1]]-c[q[mid]]))r=mid;
            else l=mid+1;
        }
        int j=q[r];
        f[i]=f[j]+1ll*(c[i]-c[j])*t[i]+1ll*(c[n]-c[j])*s;
        while(hh<tt&&(__int128)(f[q[tt]]-f[q[tt-1]])*(c[i]-c[q[tt]])>=(__int128)(f[i]-f[q[tt]])*(c[q[tt]]-c[q[tt-1]]))tt--;
        q[++tt]=i;
    }
    printf("%lld",f[n]);
    return 0;
}
posted @ 2023-04-23 21:26  wscqwq  阅读(11)  评论(0编辑  收藏  举报