#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;
typedef long long ll;
typedef pair<ll, int> P;

const ll INF = 1e17;

template <typename T>
struct segtree{
    int n;
    T UNIT;
    vector<int> dat;
    vector<T> v;
    segtree(int n_, vector<T> v_){
        UNIT = n_;
        n = 1;
        while(n < n_) n *= 2;
        dat = vector<int>(2*n);
        for(int i = 0; i < 2*n; i++) dat[i] = UNIT;
        for(ll i : v_) v.push_back(i);
        v.push_back(INF);
    }

    int calc(int a, int b){
        int ans;
        ans = (v[a] <= v[b] ? a : b);
        return ans;
    }
    void insert(int k, T a){
        dat[k+n-1] = a;
    }
    void update_all(){
        for(int i = n-2; i >= 0; i--){
            dat[i] = calc(dat[i*2+1], dat[i*2+2]);
        }
    }
    //k番目の値(0-indexed)をaに変更
    void update(int k, T a){
        k += n-1;
        dat[k] = a;
        while(k > 0){
            k = (k-1)/2;
            dat[k] = calc(dat[k*2+1], dat[k*2+2]);
        }
    }

    //[a, b)
    //区間[a, b]へのクエリに対してはquery(a, b+1)と呼ぶ
    T query(int a, int b, int k=0, int l=0, int r=-1){
        if(r < 0) r = n;
        if(r <= a || b <= l) return UNIT;
        if(a <= l && r <= b) return dat[k];
        else{
            T vl = query(a, b, k*2+1, l, (l+r)/2);
            T vr = query(a, b, k*2+2, (l+r)/2, r);
            return calc(vl, vr);
        }
    }
};

struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) { }
  bool unionSet(int x, int y) {
    x = root(x); y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y]; data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) {
    return root(x) == root(y);
  }
  int root(int x) {
    return data[x] < 0 ? x : data[x] = root(data[x]);
  }
  int size(int x) {
    return -data[root(x)];
  }
};

vector<int> u, v;

void search(int l, int r, segtree<ll> &sgtl, segtree<ll> &sgtr){
    if(l == r) return;
    int l1 = l, r1 = (l+r)/2, l2 = (l+r)/2+1, r2 = r;
    for(int i = l1; i <= r1; i++){
        int idx = sgtr.query(l2, r2+1);
        u.push_back(i);
        v.push_back(idx);
    }
    for(int i = l2; i <= r2; i++){
        int idx = sgtl.query(l1, r1+1);
        u.push_back(idx);
        v.push_back(i);
    }
    search(l1, r1, sgtl, sgtr);
    search(l2, r2, sgtl, sgtr);
}

int N;
ll D;
ll A[200000];
vector<P> p;

ll weight(int i, int j){
    return abs((ll)i-(ll)j)*D+A[i]+A[j];
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << setprecision(10) << fixed;
    cin >> N >> D;
    for(int i = 0; i  < N; i++) cin >> A[i];
    vector<ll> vl, vr;
    for(ll i = 0; i < N; i++){
        vl.push_back(A[i]-D*i);
        vr.push_back(A[i]+D*i);
    }
    segtree<ll> sgtl(N, vl);
    segtree<ll> sgtr(N, vr);
    for(int i = 0; i < N; i++){
        sgtl.update(i, i);
        sgtr.update(i, i);
    }
    UnionFind uf(N);
    search(0, N-1, sgtl, sgtr);
    ll ans = 0;
    int sz = v.size();
    for(int i = 0; i < sz; i++){
        p.push_back(P(weight(u[i], v[i]), i));
    }
    sort(p.begin(), p.end());
    for(int j = 0; j < sz; j++){
        int i = p[j].second;
        if(!uf.findSet(u[i], v[i])){
            ans += weight(u[i], v[i]);
            uf.unionSet(u[i], v[i]);
        }
    }
    cout << ans << endl;
}

Measured memory_bytes: 112516