#include "bits/stdc++.h"
#define _overload3(_1,_2,_3,name,...) name
#define _rep(i,n) repi(i,0,n)
#define repi(i,a,b) for(int i=int(a),i##_len=(b);i<i##_len;++i)
#define MSVC_UNKO(x) x
#define rep(...) MSVC_UNKO(_overload3(__VA_ARGS__,repi,_rep,_rep)(__VA_ARGS__))
#define all(c) c.begin(),c.end()
#define mp make_pair
#define write(x) cout<<(x)<<"\n"
using namespace std; typedef long long ll;
typedef vector<int> vi; typedef vector<ll> vll; template<class T>using vv = vector<vector<T>>;
template<class T>vv<T> vvec(size_t n, size_t m, T v) { return vv<T>(n, vector<T>(m, v)); }
template<class T>bool chmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
template<class T>bool chmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
constexpr int INF = 1 << 28, MOD = 1e9 + 7; constexpr ll LINF = 1ll << 60;
struct aaa { aaa() { cin.tie(0); ios::sync_with_stdio(0); }; }aaaa;
using P = pair<ll, int>;

template<typename T = int>
struct min_of {
    static const T identity;
    constexpr T operator ()(T& lhs, T& rhs) const { return lhs.first < rhs.first ? lhs : rhs; }
};
template<> const P min_of<P>::identity = P(INT64_MAX, -1);
template<typename T, class F, const T& I>
struct SegmentTree {
    const F op = F();
    int n; vector<T> dat;
    void init(int n_) { n = 1; while (n < n_) n *= 2; dat.assign(n * 2, I); }
    void build(const vector<T>& v) {
        int n_ = v.size(); init(n_);
        for (int i = 0; i < n_; i++) dat[n + i] = v[i]; for (int i = n - 1; i; i--) dat[i] = op(dat[i << 1], dat[(i << 1) + 1]); }
    void update(int k, T x) { dat[k += n] = x; while (k >>= 1) dat[k] = op(dat[k << 1], dat[(k << 1) + 1]); }
    T query(int a, int b) {
        T vl = I, vr = I;
        for (int l = a + n, r = b + n; l < r; l >>= 1, r >>= 1) { if (l & 1) vl = op(vl, dat[l++]); if (r & 1) vr = op(dat[--r], vr); }
        return op(vl, vr);
    }
    template<class C> int find(int a, int b, C & check) { return find(a, b, check, 1, 0, n); }
private:
    template<class C> int find(int a, int b, C& check, int k, int l, int r) {
        if (!check(dat[k]) || r <= a || b <= l) return -1; if (k >= n) return k - n;
        int m = (l + r) >> 1; int vl = find(a, b, check, (k << 1) | 0, l, m);
        if (~vl) return vl; return find(a, b, check, (k << 1) | 1, m, r);
    }
};

struct UnionFind {
    vector<int> parent, rank;
    int operator [](int x) { return find(x); }
    void init(int n) { parent.assign(n, -1); rank.assign(n, 0); }
    int find(int x) { return parent[x] < 0 ? x : (parent[x] = find(parent[x])); }
    bool same(int x, int y) { return find(x) == find(y); }
    int size(int x) { return -parent[find(x)]; }
    bool unite(int x, int y) {
        if ((x = find(x)) == (y = find(y))) return 0;
        rank[x] = max(rank[x], rank[y] + 1); parent[x] += parent[y]; parent[y] = x; return 1;
    }
    bool uniteByRank(int x, int y) {
        if ((x = find(x)) == (y = find(y))) return 0; else if (rank[x] < rank[y]) swap(x, y);
        else if (rank[x] == rank[y]) rank[x]++; parent[x] += parent[y]; parent[y] = x; return 1;
    }
    bool uniteBySize(int x, int y) {
        if ((x = find(x)) == (y = find(y))) return 0; else if (size(x) < size(y)) swap(x, y);
        rank[x] = max(rank[x], rank[y] + 1); parent[x] += parent[y]; parent[y] = x; return 1;
    }
};

int main() {
    ll N, D;
    cin >> N >> D;
    vector<ll> A(N);
    rep(i, N) cin >> A[i];

    vector<P> B(N);
    rep(i, N) {
        B[i] = P(A[i], i);
    }
    sort(all(B));

    vector<P> lv(N, min_of<P>::identity), rv(N, min_of<P>::identity);
    SegmentTree<P, min_of<P>, min_of<P>::identity> lst, rst;
    lst.build(lv); rst.build(rv);

    vector<pair<ll, pair<int, int>>> edge;
    rep(i, N) {
        auto lmin = lst.query(0, B[i].second);
        if (lmin.second >= 0) {
            edge.emplace_back(B[i].first + A[lmin.second] + D * abs(B[i].second - lmin.second), mp(B[i].second, lmin.second));
        }
        lst.update(B[i].second, P(B[i].first + D * (N - 1 - B[i].second), B[i].second));

        auto rmin = rst.query(B[i].second + 1, N);
        if (rmin.second >= 0) {
            edge.emplace_back(B[i].first + A[rmin.second] + D * abs(B[i].second - rmin.second), mp(B[i].second, rmin.second));
        }
        rst.update(B[i].second, P(B[i].first + D * B[i].second, B[i].second));
    }
    sort(all(edge));

    UnionFind uf;
    uf.init(N);
    ll ans = 0;
    rep(i, edge.size()) {
        if (uf.uniteByRank(edge[i].second.first, edge[i].second.second)) {
            ans += edge[i].first;
        }
    }

    write(ans);
}

Measured memory_bytes: 37868