标签:strong oid i++ 直线 data code 动态 space turn
Sample Output153Hint
solution:
然后斜率优化
因为插入的点的横坐标仍然是单调的所以并不需要动态维护凸壳。
维护下凸壳就行了
询问斜率不单调的话直接二分找直线和凸壳的切点即可。
CODE:
1 #include<cstdio>
2 #include<algorithm>
3 #define rep(i,l,r) for (int i=l; i<=r; i++)
4 typedef long long ll;
5 using namespace std;
6
7 const int N=1000010;
8 ll T[N],F[N],f[N];
9 int n,s,S,st,ed,q[N];
10
11 double Y(int j){ return f[j]-F[n]*T[j]+F[j]*T[j]-F[j]*S; }
12
13 void dp(){
14 st=ed=0;
15 rep(i,1,n){
16 int l=0,r=ed-1,ans=ed;
17 while (l<=r){
18 ll mid=(l+r)>>1;
19 if ((double)(F[q[mid+1]]-F[q[mid]])*T[i]<=Y(q[mid+1])-Y(q[mid])) ans=mid,r=mid-1; else l=mid+1;
20 }
21 int j=q[ans]; f[i]=f[j]+(F[n]-F[j])*(T[i]-T[j]+S);
22 while (st<ed && (Y(q[ed])-Y(q[ed-1]))*(F[i]-F[q[ed]])>=(Y(i)-Y(q[ed]))*(F[q[ed]]-F[q[ed-1]])) ed--;
23 q[++ed]=i;
24 }
25 }
26
27 int main(){
28
29 scanf("%d%d",&n,&S);
30 rep(i,1,n) scanf("%lld%lld",&T[i],&F[i]),T[i]+=T[i-1],F[i]+=F[i-1];
31 dp(); printf("%lld\n",f[n]);
32 return 0;
33 }
标签:strong oid i++ 直线 data code 动态 space turn
原文地址:https://www.cnblogs.com/zhangbuang/p/11134609.html