任务安排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;
}