#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define REP(i,n) for(int i=0,_n=(int)(n);i<_n;++i)
#define ALL(v) (v).begin(),(v).end()
#define CLR(t,v) memset(t,(v),sizeof(t))
template<class T1,class T2>ostream& operator<<(ostream& os,const pair<T1,T2>&a){return os<<"("<<a.first<<","<<a.second<< ")";}
template<class T>void pv(T a,T b){for(T i=a;i!=b;++i)cout<<(*i)<<" ";cout<<endl;}
template<class T>void chmin(T&a,const T&b){if(a>b)a=b;}
template<class T>void chmax(T&a,const T&b){if(a<b)a=b;}

struct UnionFind {
  vector<int> data; // 根の場合は集合の大きさ*-1、子の場合は親の番号が入る
  UnionFind(int size) : data(size, -1) { }
  bool link(int x, int y) { //新たな併合を行うとtrue
    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;
  }
  int root(int x) { // 代表元を返す
    return data[x] < 0 ? x : data[x] = root(data[x]);
  }
  int size(int x) { // 要素xが含まれる集合の大きさ
    return -data[root(x)];
  }
  bool same(int x, int y) { // 同じ集合ならtrue
    return root(x) == root(y);
  }
};

int nextInt() { int x; scanf("%d", &x); return x;}

const ll INF = 1LL << 61;

const int MAX_N = 212345;
ll A[MAX_N];

struct Edge {
  int a;
  int b;
  ll w;
  bool operator < (const Edge& o) const {
    return w < o.w;
  }
};

int main2() {
  int N = nextInt();
  ll D = nextInt();
  REP(i, N) A[i] = nextInt();

  // ブルーフカ法
  ll ans = 0;
  UnionFind uf(N);
  while (uf.size(0) < N) {

    vector<Edge> best_l(N, {0, 0, INF});
    {
      vector<pair<ll, int>> mins; // A[i]-i*D, i
      REP(i, N) {
        int ci = uf.root(i);
        for (auto m : mins) {
          int j = m.second;
          int cj = uf.root(j);
          if (cj != ci) {
            Edge e = {i, j, A[i] + A[j] + (i-j)*D};
            if (best_l[ci].w > e.w) {
              best_l[ci] = e;
            }
          }
        }
        ll w = A[i]-D*i;
        bool bat = false;
        REP(k, mins.size()) {
          if (uf.root(mins[k].second) == ci) {
            bat = true;
            if (mins[k].first > w) {
              mins[k] = {w, i};
            }
            break;
          }
        }
        if (!bat) {
          mins.push_back({w, i});
        }
        sort(ALL(mins));
        if (mins.size() > 2) mins.resize(2);
      }
    }
    vector<Edge> best_r(N, {0, 0, INF});
    {
      vector<pair<ll, int>> mins; // A[i]-i*D, i
      for (int i = N-1; i >= 0; i--) {
        int ci = uf.root(i);
        for (auto m : mins) {
          int j = m.second;
          int cj = uf.root(j);
          if (cj != ci) {
            Edge e = {i, j, A[i] + A[j] + (j-i)*D};
            if (best_l[ci].w > e.w) {
              best_l[ci] = e;
            }
          }
        }
        ll w = A[i]+D*i;
        bool bat = false;
        REP(k, mins.size()) {
          if (uf.root(mins[k].second) == ci) {
            bat = true;
            if (mins[k].first > w) {
              mins[k] = {w, i};
            }
            break;
          }
        }
        if (!bat) {
          mins.push_back({w, i});
        }
        sort(ALL(mins));
        if (mins.size() > 2) mins.resize(2);
      }
    }

    vector<Edge> es;
    REP(i, N) {
      Edge best = best_l[i].w < best_r[i].w ? best_l[i] : best_r[i];
      if (best.w < INF) {
       es.push_back(best);
        // cout << uf.size(0) << " : " << best.a << " " << best.b << " " << best.w << endl;
      }
    }
    sort(ALL(es));
    for (Edge e : es) {
      if (uf.link(e.a, e.b)) {
        ans += e.w;
      }
    }
  }

  cout << ans << endl;
  return 0;
}

int main() {
  for (;!cin.eof();cin>>ws)
    main2();
  return 0;
}


Measured memory_bytes: 14960