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

时间:2023-03-09 13:14:53
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;
}