#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#include<random>
#include<array>
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;
void iosetup() {
    cin.tie(nullptr);ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
}

//----------------------- 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(){
    iosetup();
    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;
    rep(i, 0, N){
        pll p(INFLL, INF), q(INFLL, INF);
        if(0 < i){
            p = sl.rmq(0, i);
            p.first += i * D + A[i];
        }
        if(i + 1 < N){
            q = sr.rmq(i + 1, N);
            q.first += -i * D + A[i];
        }
        chmin(p, q);
        if(uf.same(i, p.second)) continue;
        uf.unite(i, p.second);
        ans += p.first;
    }

    int l = 0;
    while(l < N and uf.find(0) == uf.find(l)) ++l;
    while(l < N){
        int r = l + 1;
        while(r < N and uf.find(l) == uf.find(r)) ++r;

        int p = sl.rmq(0, l).second;
        int q = sr.rmq(l, r).second;

        ans += abs(p - q) * D + A[p] + A[q];
        l = r;
    }
    cout << ans << endl;

    return 0;
}

Measured memory_bytes: 163340