#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
template <class T>
inline bool MX(T &l, const T &r) {
  return l < r ? l = r, 1 : 0;
}
template <class T>
inline bool MN(T &l, const T &r) {
  return l > r ? l = r, 1 : 0;
}
const long long INF = 1LL << 61;
int N;
int size;
long long D;
long long A[214514];
pair<long long, long long> seg1[1 << 23];
pair<long long, long long> seg2[1 << 23];
void Update(pair<long long, long long> *seg, int k,
            pair<long long, long long> x) {
  k += size - 1;
  seg[k] = x;
  while (k > 0) {
    k = (k - 1) / 2;
    seg[k] = min(seg[k * 2 + 1], seg[k * 2 + 2]);
  }
}
pair<long long, long long> GetMin(pair<long long, long long> *seg, int wishl,
                                  int wishr, int k, int watchl, int watchr) {
  int mid;
  pair<long long, long long> lval, rval;
  if (wishr <= watchl || watchr <= wishl)
    return pair<long long, long long>(INF, INF);
  if (wishl <= watchl && watchr <= wishr) return seg[k];
  mid = (watchl + watchr) / 2;
  lval = GetMin(seg, wishl, wishr, k * 2 + 1, watchl, mid);
  rval = GetMin(seg, wishl, wishr, k * 2 + 2, mid, watchr);
  return min(lval, rval);
}
using Edge = pair<long long, pair<int, int> >;
struct UfData {
  int parsz;
  UfData() : parsz(-1) {}
  void Merge(const UfData &d, int u, int v) { parsz += d.parsz; }
};
struct UnionFind {
  vector<UfData> dat;
  UnionFind() {}
  UnionFind(int n) { Init(n); }
  void Init(int n) { dat.assign(n, UfData()); }
  int Root(int v) {
    if (dat[v].parsz < 0) return v;
    return dat[v].parsz = Root(dat[v].parsz);
  }
  bool Unite(int u, int v) {
    int p = Root(u);
    int q = Root(v);
    if (p == q) return false;
    if (dat[p].parsz > dat[q].parsz) {
      swap(p, q);
      swap(u, v);
    }
    dat[p].Merge(dat[q], u, v);
    dat[q].parsz = p;
    return true;
  }
  bool Same(int u, int v) { return Root(u) == Root(v); }
  int Size(int v) { return -dat[Root(v)].parsz; }
  UfData &Data(int v) { return dat[Root(v)]; }
};
signed main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(0);
  cin >> N >> D;
  size = 1;
  while (size < N) size <<= 1;
  for (int(i) = 0; (i) < (N); ++(i)) {
    cin >> A[i];
    Update(seg1, i, pair<long long, long long>(A[i] + i * D, i));
    Update(seg2, i, pair<long long, long long>(A[i] + (N - i) * D, i));
  }
  vector<Edge> es;
  for (int(v) = 0; (v) < (N); ++(v)) {
    {
      vector<pair<long long, long long> > restore;
      for (int(k) = 0; (k) < (10); ++(k)) {
        pair<long long, long long> p = GetMin(seg1, v + 1, N, 0, 0, size);
        if (p.first != INF) {
          es.emplace_back(Edge(A[v] + A[p.second] + abs(v - p.second) * D,
                               pair<int, int>(v, p.second)));
          restore.emplace_back(p);
          Update(seg1, p.second, pair<long long, long long>(INF, INF));
        }
      }
      for (auto &p : restore) {
        Update(seg1, p.second, p);
      }
    }
    vector<pair<long long, long long> > restore;
    for (int(k) = 0; (k) < (10); ++(k)) {
      pair<long long, long long> q = GetMin(seg2, 0, v, 0, 0, size);
      if (q.first != INF) {
        es.emplace_back(Edge(A[v] + A[q.second] + abs(v - q.second) * D,
                             pair<int, int>(v, q.second)));
        restore.emplace_back(q);
        Update(seg2, q.second, pair<long long, long long>(INF, INF));
      }
    }
    for (auto &p : restore) {
      Update(seg2, p.second, p);
    }
  }
  sort((es).begin(), (es).end());
  long long ans = 0;
  UnionFind uf(N);
  for (Edge &e : es) {
    long long c = e.first;
    int u, v;
    tie(u, v) = e.second;
    if (uf.Same(u, v)) continue;
    ans += c;
    uf.Unite(u, v);
  }
  cout << ans << "\n";
}
