#include <bits/stdc++.h>
using namespace std;
const long long N = 200005;
vector<long long> pai, peso;
long long A[N];
long long best[N];
long long n, D;
void init(long long N) {
  for (long long i = 0; i <= N; i++) pai[i] = i, peso[i] = 1;
}
long long fd(long long x) { return pai[x] == x ? x : pai[x] = fd(pai[x]); }
void join(long long u, long long v) {
  u = fd(u), v = fd(v);
  if (peso[u] > peso[v]) swap(u, v);
  pai[u] = v, peso[v] += peso[u];
}
struct node {
  long long vl, idx;
};
node merge(node a, node b) {
  node x;
  if (a.vl < b.vl)
    x = a;
  else
    x = b;
  return x;
}
node st[4 * N];
void update(long long x, long long vl, long long idx, long long l = 1,
            long long r = n, long long curr = 1) {
  long long mid = (l + r) / 2;
  if (l == r && l == x) {
    if (st[curr].vl > vl) st[curr].vl = vl, st[curr].idx = idx;
    return;
  }
  if (x <= mid)
    update(x, vl, idx, l, mid, 2 * curr);
  else
    update(x, vl, idx, mid + 1, r, 2 * curr + 1);
  st[curr] = merge(st[2 * curr + 1], st[2 * curr]);
}
node query(long long x, long long y, long long l = 1, long long r = n,
           long long curr = 1) {
  long long mid = (l + r) / 2;
  if (l == x && r == y) {
    return st[curr];
  }
  if (y <= mid)
    return query(x, y, l, mid, 2 * curr);
  else if (x > mid)
    return query(x, y, mid + 1, r, 2 * curr + 1);
  return merge(query(x, mid, l, mid, 2 * curr),
               query(mid + 1, y, mid + 1, r, 2 * curr + 1));
}
struct edge {
  long long x, y, z;
};
int32_t main() {
  scanf("%lld%lld", &n, &D);
  peso.resize(n + 1), pai.resize(n + 1);
  init(n);
  for (long long i = 1; i <= n; i++) scanf("%lld", &A[i]);
  long long ans = 0;
  long long rcnt = 0;
  while (peso[fd(1)] != n) {
    for (long long i = 0; i < 4 * N; i++) {
      st[i].vl = (long long)1e16;
      st[i].idx = -1;
    }
    for (long long i = 1; i <= n; i++) best[i] = -1;
    for (long long i = 1; i <= n; i++) {
      long long U = fd(i);
      node W, K;
      W.idx = -1, W.vl = (long long)1e16;
      K.idx = -1, K.vl = (long long)1e16;
      if (U > 1) W = query(1, U - 1);
      if (U < n) K = query(U + 1, n);
      if (W.idx != -1 && K.idx != -1) {
        if (W.vl < K.vl)
          best[i] = W.idx;
        else
          best[i] = K.idx;
      } else if (W.idx != -1)
        best[i] = W.idx;
      else if (K.idx != -1)
        best[i] = K.idx;
      update(fd(i), A[i] - i * D, i);
    }
    for (long long i = 0; i < 4 * N; i++) {
      st[i].vl = (long long)1e18;
      st[i].idx = -1;
    }
    for (long long i = n; i >= 1; i--) {
      long long U = fd(i);
      node W, K;
      W.idx = -1, W.vl = (long long)1e18;
      K.idx = -1, K.vl = (long long)1e18;
      if (U > 1) W = query(1, U - 1);
      if (U < n) K = query(U + 1, n);
      long long newbest = -1;
      if (W.idx != -1 && K.idx != -1) {
        if (W.vl < K.vl)
          newbest = W.idx;
        else
          newbest = K.idx;
      } else if (W.idx != -1)
        newbest = W.idx;
      else if (K.idx != -1)
        newbest = K.idx;
      if (newbest != -1) {
        if (best[i] == -1) {
          best[i] = newbest;
        } else {
          if ((A[i] + A[best[i]] + abs(best[i] - i) * D) >
              (A[i] + A[newbest] + abs(newbest - i) * D))
            best[i] = newbest;
        }
      }
      update(fd(i), A[i] + i * D, i);
    }
    vector<edge> R;
    for (long long i = 1; i <= n; i++) {
      if (best[i] == -1) continue;
      if (fd(best[i]) != fd(i)) {
        R.push_back({i, best[i], abs(best[i] - i) * D + A[best[i]] + A[i]});
      }
    }
    sort(R.begin(), R.end(), [&](edge a, edge b) { return a.z < b.z; });
    set<long long> WW;
    for (auto w : R) {
      if (fd(w.x) != fd(w.y)) {
        if (WW.count(fd(w.x))) continue;
        WW.insert(fd(w.x));
        join(w.x, w.y);
        ans += w.z;
      }
    }
  }
  printf("%lld\n", ans);
}
