还是斜率优化。还是很简单。略过。注意一下B的那一项是可以分离出来的,和i、j都是无关的,速度快点。这里没有给出实现。
但是C是不能分离的,分离出来,C是和分的数量有关的,就会方程必须增加一维。。。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
typedef long long ll;
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
long q[1000005];
long n;
long A;
long B;
long C;
long fight[1000010];
ll sum[1000010];
ll f[1000010];
long que[1000010];
long l = 0;
long r = 0;
inline long getint()
{
long ret = 0;
char tmp;
while (!isdigit(tmp = getchar()));
do {
ret = (ret << 3)+(ret << 1) + tmp - '0';
} while (isdigit(tmp = getchar()));
return ret;
}
ll Calc(long j,long k)
{
return f[j]-f[k]+A*(sum[j]*sum[j]-sum[k]*sum[k])-B*(sum[j]-sum[k]);
}
int main()
{
freopen("commando.in","r",stdin);
freopen("commando.out","w",stdout);
n = getint();
A = -getint();
scanf("%ld%ld",&B,&C);
for (long i=1;i<n+1;++i)
{
fight[i] = getint();
sum[i] = sum[i-1]+(ll)fight[i];
}
//A < 0
//Initializaion
for (long i=1;i<n+1;i++)
f[i] = -0x7f7f7f7f;
for (long i=1;i<n+1;i++)
{
while (l<r&&Calc(q[l],q[l+1])<=2*A*sum[i]*(sum[q[l]]-sum[q[l+1]]))l++;
long ch = q[l];long x=sum[i]-sum[ch];
f[i] = f[ch] + A*x*x+x*B+C;
while (l<r&&Calc(q[r-1],q[r])*(sum[q[r]]-sum[i])<=Calc(q[r],i)*(sum[q[r-1]]-sum[q[r]]))r--;
q[++r] = i;
}
std::cout << f[n];
return 0;
}