第一次做这题的时候看的别人的博客,迷迷糊糊就过去了。。回来看发现不太懂,自己再学了学,理解得深了一点。。
#include<iostream>
#include<cstdio>
#include<memory.h>
#include<cstdlib>
#define ll long long
#define q1 que[head]
#define q2 que[head+1]
#define t1 que[tail]
#define t2 que[tail-1]
using namespace std;
int i,j,n,head,tail,c[50005],que[50005];
ll dp[50005],f[50005],l,C;
ll H(int i) {return (ll)f[i]*f[i]+2*f[i]*C+C*C;}
ll G(int i) {return (ll)f[i]*f[i]-2*f[i]*C+dp[i];}
ll get(int i)
{
while (2*f[i]*(f[q2]-f[q1])>G(q2)-G(q1)&&tail-head>0) head++;
return -2*f[q1]*f[i]+G(q1)+H(i);
}
void ins(int i)
{
while (tail-head>0&&(G(i)-G(t1))*(f[t1]-f[t2])<(G(t1)-G(t2))*(f[i]-f[t1])) tail--;
que[++tail]=i;
}
int main()
{
freopen("1010.in","r",stdin);
scanf("%d%I64d",&n,&l);
f[0]=dp[0]=0ll;C=-l-1;
for (i=1;i<=n;i++)
{
scanf("%d",&c[i]);
f[i]=f[i-1]+(ll)c[i]+1;
}
head=tail=1;que[1]=0;que[++tail]=1;
dp[1]=-2*f[0]*f[1]+G(0)+H(1);
for (i=2;i<=n;i++)
{
dp[i]=get(i);
ins(i);
}
cout<<dp[n];
}