题解:P10979 任务安排 2
__Inv_day_in_R__ · · 题解
本题是 P2365 的强化版,先思考 P2365 怎么做。
我们用
这里使用前缀和优化,最终,得到如下的转移方程:
时间复杂度
接下来考虑本题的斜率优化。斜率优化需要对原方程进行变形,先省略
化成这个形式之后,发现像一个一次函数,于是以
不难发现,答案必然在原点集的一个右下凸包上:
考虑如何动态维护凸包。
如上图,CD 斜率大于 DE 斜率,所以 D 被删除,然后再看 BC 与 CE。
查询时二分即可。 代码如下:
#include<iostream>
#define int long long
using namespace std;
int n,s,t[300010],c[300010],f[300010];
int q[300010];
main(){
cin>>n>>s;
for(int i=1;i<=n;i++){
cin>>t[i]>>c[i];
t[i]+=t[i-1];
c[i]+=c[i-1];
}
int hh=0,tt=0;
q[0]=0;
for(int i=1;i<=n;i++){
int l=hh,r=tt;
while(l<r){
int mid=l+r>>1;
if((__int128)(t[i]+s)*(c[q[mid+1]]-c[q[mid]])<(__int128)(f[q[mid+1]]-f[q[mid]]))r=mid;
else l=mid+1;
}
int j=q[r];
f[i]=f[j]+c[i]*t[i]-c[j]*t[i]+c[n]*s-c[j]*s;
while(hh<tt&&(__int128)(f[i]-f[q[tt]])*(c[q[tt]]-c[q[tt-1]])<=(__int128)(f[q[tt]]-f[q[tt-1]])*(c[i]-c[q[tt]]))tt--;
q[++tt]=i;
}
cout<<f[n];
}
这个代码还能过 P5785。