这是一道斜率优化简单题,但是他不给清楚数据范围。注意:
不会斜率优化,请戳这里。
设。
则有:
化成
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e5+10;
int n,m,q[N],l,r;
ll f[N],s[N];
double y(int i){return (double)f[i]+s[i]*s[i];}
double x(int i){return (double)s[i];}
double slope(int i,int j)
{
return (y(i)-y(j))/(x(i)-x(j));
}
#define g getchar()
template<class o>//快读
void qr(o&x)
{
char c=g;bool v=x=0;
while(!( ('0'<=c&&c<='9') || c=='-' ))c=g;
if(c=='-')v=1,c=g;
while('0'<=c&&c<='9')x=x*10+c-'0',c=g;
if(v)x=-x;
}
#undef g
int main()
{
while(~scanf("%d",&n))
{
qr(m);
for(int i=1;i<=n;i++)
{
qr(s[i]);
if(!s[i]){i--,n--;continue;}//坑点。
s[i]=s[i]+s[i-1];
}
l=r=1;q[1]=0;
#define j q[l]
for(int i=1;i<=n;i++)
{
while(l<r&&slope(q[l],q[l+1])<=(double)(s[i]<<1))l++;
f[i]=f[j]+(s[i]-s[j])*(s[i]-s[j])+m;
while(l<r&&slope(q[r-1],q[r])>=slope(q[r],i))r--;
q[++r]=i;
}
#undef j
printf("%lld
",f[n]);
}
return 0;
}