#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;
using ll = long long;
#define rep(i, a, b) for(int i = a; i < b; i++)
#define rrep(i, a, b) for(int i = b - 1; i >= a; i--)
#define ALL(a) a.begin(), a.end()
template<class T>inline bool chmax(T &a, const T &b) {if(a<b){a = b; return 1;} return 0; };
template<class T>inline bool chmin(T &a, const T &b) {if(a>b){a = b; return 1;} return 0; };
const int INF = 1e9;
const long long INFLL = 1e18;

//----------------------- edit from here ---------------------------------

using pii = pair<int,int>;
using pll = pair<long long, long long>;

// ref: https://ei1333.github.io/luzhiled/snippets/structure/sparse-table.html 
template< typename T >
struct SparseTable {
    vector< vector< T > > st;
    vector< int > lookup;

    SparseTable(const vector< T > &v) {
        int b = 0;
        while((1 << b) <= v.size()) ++b;
        st.assign(b, vector< T >(1 << b));
        for(int i = 0; i < v.size(); i++) {
            st[0][i] = v[i];
        }
        for(int i = 1; i < b; i++) {
            for(int j = 0; j + (1 << i) <= (1 << b); j++) {
                st[i][j] = min(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
            }
        }
        lookup.resize(v.size() + 1);
        for(int i = 2; i < lookup.size(); i++) {
            lookup[i] = lookup[i >> 1] + 1;
        }
    }

    inline T rmq(int l, int r) {
        int b = lookup[r - l];
        return min(st[b][l], st[b][r - (1 << b)]);
    }
};
// SparseTable< int > table(vs); // vs := init vector;
// table.rmq(l, r) // min in [l, r)

// ref: https://ei1333.github.io/luzhiled/snippets/structure/union-find.html
struct UnionFind {
    vector< int > data;
 
    UnionFind(int sz) {
        data.assign(sz, -1);
    }
    
    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if(x == y) return (false);
        if(data[x] > data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        return (true);
    }
    
    int find(int k) {
        if(data[k] < 0) return (k);
        return (data[k] = find(data[k]));
    }
    
    int size(int k) {
        return (-data[find(k)]);
    }

    bool same(int x, int y){
        return find(x) == find(y);
    }
};


int main(){
    cin.tie(nullptr);ios::sync_with_stdio(false);
    ll N, D; cin >> N >> D;
    vector<ll> A(N);
    rep(i, 0, N) cin >> A[i];

    vector<pll> le(N), ri(N);
    rep(i, 0, N) le[i] = pll(A[i] - D * i, i);
    rep(i, 0, N) ri[i] = pll(A[i] + D * i, i);
    SparseTable<pll> sl(le), sr(ri);
    UnionFind uf(N);
    ll ans = 0;
    while(uf.size(0) < N){
        set<pii> st; // edge set for merge
        int l = 0;
        // search minimum cost edge for each connected component
        while(l < N){
            int r = l;
            while(r < N and uf.same(l, r)) r++;
            pll lp(INFLL, INF), rq(INFLL, INF), cp(INFLL, INF), cq(INFLL, INF);
            if(0 < l){
                lp = sl.rmq(0, l);
                cp = sr.rmq(l, r);
            }
            if(r < N){
                rq = sr.rmq(r, N);
                cq = sl.rmq(l, r);
            }
            if(lp.first == INFLL and rq.first == INFLL) continue;
            if(lp.first + cp.first < rq.first + cq.first){
                st.emplace(lp.second, cp.second);
            }else{
                st.emplace(rq.second, cq.second);
            }
            l = r;
        }
        // merge
        for(auto& e: st){
            int l = e.first, r = e.second;
            if(uf.same(l, r)) continue;
            uf.unite(l, r);
            ans += D * abs(l - r) + A[l] + A[r];
        }
    }
    cout << ans << endl;

    return 0;
}

Measured memory_bytes: 170260