1 //经过适当推式子可得当slope(j,k)>f[i] (j<k)时,k是优的
2 #include<cstdio>
3 #include<cstring>
4 #include<iostream>
5 using namespace std;
6
7 typedef long long ll;
8
9 const int maxn=50005;
10
11 int l=1,r=1,n,L;
12
13 //用类似(其实就是?)单调队列的数据结构维护最大值,使状态O(1)转移
14 long long s[maxn],f[maxn],dp[maxn],q[maxn];
15
16 double slope(int a,int b){
17 return (dp[a]-dp[b]+(f[a]+L)*(f[a]+L)-(f[b]+L)*(f[b]+L))/(2.0*(f[a]-f[b]));
18 }
19
20 int main(){
21 scanf("%d%d",&n,&L); L++;
22 //预处理数据,简化公式
23 for(int i=1;i<=n;i++) scanf("%d",&s[i]),s[i]+=s[i-1],f[i]=s[i]+i;
24 for(int i=1;i<=n;i++){
25 //不优,pop队首
26 while(l<r&&slope(q[l],q[l+1])<=f[i]) l++;
27 dp[i]=dp[q[l]]+(f[i]-f[q[l]]-L)*(f[i]-f[q[l]]-L);
28 //不满足凸壳性质,pop队尾(维护下凸壳)
29 while(l<r&&slope(q[r-1],q[r])>slope(q[r],i)) r--;
30 q[++r]=i;
31 }
32 printf("%lld\n",dp[n]);
33 return 0;
34 }