#include <bits/stdc++.h>
using namespace std;
#define int long long
#define stoi stoll
using ll=long long;
using vi=vector<int>;
using pii=pair<int,int>;
#define ALL(c) begin(c),end(c)
#define RALL(c) rbegin(c),rend(c)
#define ITR(i,b,e) for(auto i=(b);i!=(e);++i)
#define FORE(x,c) for(auto &&x:c)
#define REPF(i,a,n) for(int i=a,i##len=(int)(n);i<i##len;++i)
#define REP(i,n) REPF(i,0,n)
#define REPR(i,n) for(int i=(int)(n);i>=0;--i)
#define SZ(c) ((int)c.size())
#define CONTAIN(c,x) (c.find(x)!=end(c))
#define INSEG(l,x,r) ((l)<=(x)&&(x)<(r))
#define dump(...)
#define pb push_back
#define _ 0
const signed INF_=1001001001; const long long INF=1001001001001001001LL;
const int DX[9]={0,1,0,-1,1,1,-1,-1,0},DY[9]={-1,0,1,0,-1,1,1,-1,0};
template<class T> ostream& operator<<(ostream &os,const vector<T> &v) {
    ITR(i,begin(v),end(v))os<<*i<<(i==end(v)-1?"":" ");return os;}
template<class T> istream& operator>>(istream &is,vector<T> &v) {
    ITR(i,begin(v),end(v)) is>>*i;return is;}
template<class T,class U> istream& operator>>(istream &is, pair<T,U> &p) {
    is>>p.first>>p.second;return is;}
template<class T, class U> bool chmax(T &a,const U &b){return a<b?a=b,1:0;}
template<class T, class U> bool chmin(T &a,const U &b){return a>b?a=b,1:0;}
template <class T> void PSUM(T& c) {partial_sum(begin(c), end(c), begin(c));}
template<class T> using heap=priority_queue<T,vector<T>,greater<T>>;
struct before_main_function {
    before_main_function() {
        cin.tie(0); ios::sync_with_stdio(false);
        cout << setprecision(15) << fixed;
        #define endl "\n"
    }
} before_main_function;
//------------------8<------------------------------------8<--------------------


using CHT_TYPE = ll;
class ConvexHullTrickDynamic {
private:
    // 直線 **************************************************************
    struct Line {
        CHT_TYPE a, b; // y = ax + b
        mutable std::function<const Line*()> getSuc; // 次の直線へのポインタ (ソートで用いる)

        bool operator<(const Line& rhs) const {
            // 取得クエリでは次の直線との差分でソート
            if (rhs.b == IS_QUERY) {
                const Line* suc = getSuc();
                if (suc == nullptr) return false;
                const CHT_TYPE& x = rhs.a;
                return (suc->a - a)*x + suc->b - b > 0;
            }
            if (b == IS_QUERY) {
                const Line* suc = rhs.getSuc();
                if (suc == nullptr) return true;
                const CHT_TYPE& x = a;
                return (suc->a - rhs.a)*x + suc->b - rhs.b < 0;
            }

            // 通常の直線どうしは傾きソート
            return a < rhs.a;
        }
    };

    // 直線集合 **********************************************************
    class LinesSet : public std::multiset<Line> {
    private:
        // true -> 最小値クエリ, false -> 最大値クエリ
        bool flagMin;

    public:
        // コンストラクタ ( 第一引数falseで最大値クエリ,デフォルトで最小値クエリ )
        LinesSet(bool flagMin = true) : flagMin(flagMin) {};

        // 直線lが不必要であるかどうか
        inline bool isBad(iterator l) {
            const auto&& nel = std::next(l);
            if (l == begin()) { // lが傾き最小のとき
                if (nel == end()) return false; // lしかないなら必要
                return l->a == nel->a && l->b <= nel->b;
            }
            else {
                const auto&& prl = std::prev(l);
                if (nel == end()) return l->a == prl->a && l->b <= prl->b;
                return (prl->b - l->b) * (nel->a - l->a) >= (nel->b - l->b) * (prl->a - l->a);
            }
        }

        // 直線y=ax+bを追加する
        inline void add(CHT_TYPE a, CHT_TYPE b) {
            if (flagMin) a = -a, b = -b;
            auto&& it = insert({a, b});
            it->getSuc = [=] { return (std::next(it) == end() ? nullptr : &*std::next(it)); };
            if (isBad(it)) { erase(it); return; }
            while (std::next(it) != end() && isBad(std::next(it))) erase(std::next(it));
            while (it != begin() && isBad(std::prev(it))) erase(std::prev(it));
        }

        // 直線群の中でxの時に最小(最大)となる値を返す
        inline CHT_TYPE get(CHT_TYPE x) {
            auto&& l = *lower_bound(Line{x, IS_QUERY});
            if (flagMin) return -l.a * x - l.b;
            else return l.a * x + l.b;
        }
    };

    static const CHT_TYPE IS_QUERY = std::numeric_limits<CHT_TYPE>::lowest();
    LinesSet linesSet;

public:
    // コンストラクタ ( 第一引数falseで最大値クエリ,デフォルトで最小値クエリ )
    ConvexHullTrickDynamic(bool flagMin = true) : linesSet(flagMin) {}
    // 直線y=ax+bを追加する
    inline void add(CHT_TYPE a, CHT_TYPE b) { linesSet.add(a, b); }
    // あるxのときの直線集合での最小値を求める
    inline CHT_TYPE get(CHT_TYPE x) { return linesSet.get(x); }
};
// quoted from: https://github.com/satanic0258/Cpp_snippet/blob/master/src/technique/ConvexHullTrick.cpp

signed main() {
    int N, C;
    cin >> N >> C;
    vector<int> h(N);
    cin >> h;

    vector<int> dp(N);
    ConvexHullTrickDynamic cht;
    auto add = [&](int idx) {
        cht.add(-2 * h[idx], h[idx] * h[idx] + dp[idx]);
    };

    dp[0] = 0;
    add(0);

    REPF(i, 1, N) {
        dp[i] = cht.get(h[i]) + C + h[i] * h[i];
        add(i);
    }

    cout << dp[N - 1] << endl;
    return (0^_^0);
}



Measured memory_bytes: 22144