斜率dp入门
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#pragma comment(linxer, "/STACK:102400000,102400000")
#define LL long long
#define pii pair<int, int>
#define MP make_pair
#define ls i << 1
#define rs ls | 1
#define md (ll + rr >> 1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define mod 1000000007
#define inf 0x3f3f3f3f
#define N 500010
#define M 200020
int c[N], s[N], q[N], dp[N];
int x[N], y[N];
int cross(int ax, int ay, int bx, int by){
return 1LL * ax * by - 1LL * ay * bx;
}
bool check1(int i, int j, int k){
return y[j] - y[i] <= k * (x[j] - x[i]);
}
int main(){
int n, m;
while(scanf("%d%d", &n, &m) != EOF){
memset(q, 0, sizeof q);
for(int i = 1; i <= n; ++i)
scanf("%d", &c[i]), s[i] = s[i-1] + c[i];
int head = 0, tail = 0;
q[tail++] = 0;
for(int i = 1; i <= n; ++i){
while(head + 1 < tail){
if(check1(q[head], q[head + 1], s[i])) head++;
else break;
}
dp[i] = dp[q[head]] + (s[i] - s[q[head]]) * (s[i] - s[q[head]]) + m;
x[i] = 2 * s[i];
y[i] = s[i] * s[i] + dp[i];
while(head + 1 < tail){
if(cross(x[q[tail-1]] - x[i], y[q[tail-1]] - y[i], x[q[tail-2]] - x[i], y[q[tail-2]] - y[i]) >= 0) tail--;
else break;
}
q[tail++] = i;
}
printf("%d\n", dp[n]);
}
return 0;
}