fi=max{fj+a(si−sj)2+b∗(si−sj)+c}
f
i
=
m
a
x
{
f
j
+
a
(
s
i
−
s
j
)
2
+
b
∗
(
s
i
−
s
j
)
+
c
}
若
t
t
比优,即
令 gi=fi+a∗s2i−b∗si g i = f i + a ∗ s i 2 − b ∗ s i
上凸壳
代码如下:
#include<ctype.h>
#include<cstdio>
#define INF 21474836470000000ll
#define N 1000200
using namespace std;
inline int read(){
int x=0,f=1;char c;
do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c));
do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c));
return x*f;
}
typedef long long LL;
int n,a,b,c,l,r;
LL s[N],f[N];
struct Point{
LL x,y;
Point(){}
Point(LL _,LL __):x(_),y(__){}
}q[N],tmp;
inline double Slope(Point a,Point b){
if(a.x==b.x) return a.y>b.y?-INF:INF;
return 1.0*(b.y-a.y)/(b.x-a.x);
}
int main(){
n=read();
a=read();b=read();c=read();
for(int i=1;i<=n;i++)
s[i]=s[i-1]+read();
for(int i=1;i<=n;i++){
while(l<r && Slope(q[l],q[l+1])>s[i]*a*2) l++;
f[i]=q[l].y+a*s[i]*s[i]-a*s[i]*q[l].x*2+b*s[i]+c;
tmp=Point(s[i],f[i]-b*s[i]+a*s[i]*s[i]);
while(l<r && Slope(q[r],tmp)>Slope(q[r-1],q[r])) r--;
q[++r]=tmp;
}
printf("%lld",f[n]);
return 0;
}