#include <bits/stdc++.h>
 
using namespace std;
using ll = long long;
// #define int ll
using PII = pair<ll, ll>;
 
#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define endl '\n'
 
template<typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template<typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }
 
template<typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts) { 
  return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}
template<typename T,typename V> typename enable_if<is_class<T>::value==0>::type
fill_v(T &t, const V &v) { t=v; }
template<typename T,typename V> typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t, const V &v ) { for(auto &e:t) fill_v(e,v); }
 
template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a){
  out<<'('<<a.first<<','<<a.second<<')'; return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
  out<<'['; for(T i: a) {out<<i<<',';} out<<']'; return out;
}
 
int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // DRUL
const int INF = 1<<30;
const ll LLINF = 1LL<<60;
const int MOD = 1000000007;

// template< typename T, typename F >
// T boruvka(ll n, F f) {
//   vector<ll> rev(n), belong(n);
//   UnionFind uf(n);
//   T ret = T();
//   while(uf.size(0) != n) {
//     ll ptr = 0;
//     REP(i, n) {
//       if(uf.find(i) == i) {
//         belong[i] = ptr++;
//         rev[belong[i]] = i;
//       }
//     }
//     REP(i, n) belong[i] = belong[uf.find(i)];
//     auto v = f(ptr, belong);
//     bool update = false;
//     REP(i, ptr) {
//       if(~v[i].second && !uf.same(rev[i], rev[v[i].second])) {
//         uf.unite(rev[i], rev[v[i].second]);
//         ret += v[i].first;
//         update = true;
//       }
//     }
//     if(!update) return -1; // notice!!
//   }
//   return ret;
// }

struct quickfind {
  vector<int> par;
  vector<vector<int>> vs;
  quickfind() {}
  quickfind(int n) : par(n), vs(n) {
    REP(i, n) par[i] = i, vs[i].push_back(i);
  }
  int root(int a) { return par[a]==a ? a : par[a] = root(par[a]); }
  bool unite(int a, int b) {
    a = root(a), b = root(b);
    if(a == b) return false;
    if(vs[a].size() > vs[b].size()) swap(a, b);
    par[b] = a;
    for(int x: vs[b]) vs[a].push_back(x);
    vs[b].clear();
    return true;
  }
  int same(int a, int b) { return root(a) == root(b); }
  int size(int a) { return vs[root(a)].size(); }
};

template <typename T>
struct segtree {
  int n;
  vector<T> dat;
  T d;

  segtree(int n_, T d_) : d(d_) {
    n = 1; while(n < n_) n *= 2;
    dat.assign(n*2, d); 
  }
  // [a, b)
  T query(int a, int b, int k, int l, int r) {
    if(r <= a || b <= l) return d;
    if(a <= l && r <= b) return dat[k];
    return min(query(a, b, 2*k+1, l, (l+r)/2),
               query(a, b, 2*k+2, (l+r)/2, r));
  }
  T query(int a, int b) {return query(a, b, 0, 0, n);}
  void update(int i, T v) {
    i += n-1;
    dat[i] = v;
    while(i > 0) {
      i = (i-1)/2;
      dat[i] = min(dat[i*2+1], dat[i*2+2]);
    }
  }
};
/**
* 点更新区間min d=INF, f=min(a,b), g=b\n
* 点更新区間max d=-INF, f=max(a,b), g=b\n
* 点加算区間和  d=0, f=a+b, g+=b
*/

signed main(void)
{
  cin.tie(0);
  ios::sync_with_stdio(false);

  ll n, d;
  cin >> n >> d;
  vector<ll> a(n);
  REP(i, n) cin >> a[i];

  // 区間最小のセグ木
  segtree<PII> seg1(n, make_pair(LLINF,LLINF)),
               seg2(n, make_pair(LLINF,LLINF));
  REP(i, n) {
    seg1.update(i, {a[i]-i*d, i});
    seg2.update(i, {a[i]+i*d, i});
  }

  ll ans = 0;
  quickfind qf(n);
  while(qf.size(0) != n) {
    vector<pair<PII,ll>> es;
    REP(i, n) if(qf.root(i) == i) {
      PII e(-1, -1);
      ll mi = LLINF;
      for(auto x: qf.vs[i]) {
        seg1.update(x, {LLINF,LLINF});
        seg2.update(x, {LLINF,LLINF});
      }
      for(auto x: qf.vs[i]) {
        auto p = seg1.query(0, x);
        if(mi > p.first + a[x] + x*d) {
          mi = p.first + a[x] + x*d;
          e = PII(x, p.second);
        }
        p = seg2.query(x+1, n);
        if(mi > p.first + a[x] - x*d) {
          mi = p.first + a[x] - x*d;
          e = PII(x, p.second);
        }
      }
      for(auto x: qf.vs[i]) {
        seg1.update(x, {a[x]-x*d, x});
        seg2.update(x, {a[x]+x*d, x});
      }
      es.push_back({e, mi});
    }
    for(auto x: es) {
      PII p = x.first;
      if(qf.unite(p.first, p.second)) {
        ans += x.second;
      }
    }
  }
  cout << ans << endl;

  // // 各頂点から最小のコストの辺を求める 
  // // f(連結成分数、i番目の頂点が属する連結成分)
  // function<vector<PII>(ll,vector<ll>)> f = [&](ll sz, vector<ll> belong) {
  //   // ret[i] = (頂点iからコスト最小の辺の(コスト, i以外の端点))
  //   // iがufの親以外ならsecondは-1として連結成分ごとに管理
  //   vector<PII> ret(sz, PII(LLINF, -1));
  //   // 連結成分ごとにまとめる
  //   vector<vector<ll>> member(sz);
  //   REP(i, n) member[belong[i]].push_back(i);
  //   for(auto v: member) {
  //     for(auto i: v) {
  //       seg1.update(i, make_pair(LLINF, LLINF));
  //       seg2.update(i, make_pair(LLINF, LLINF));
  //     }
  //     for(auto i: v) {
  //       auto vl = seg1.query(0, i); vl.first += a[i] + i*d;
  //       auto vr = seg2.query(i+1, n); vr.first += a[i] - i*d;
  //       chmin(ret[belong[i]], min(vl, vr)); 
  //     }
  //     REP(i, v.size()) {
  //       seg1.update(v[i], {a[i]-i*d, i});
  //       seg2.update(v[i], {a[i]+i*d, i});
  //     }
  //   }
  //   return ret;
  // };

  // cout << boruvka<ll, decltype(f)>(n, f) << endl;

  return 0;
}
