#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, int>;
const ll INF = 1000000000000000LL;
template <typename T>
struct SegmentTree {
  int n;
  vector<T> data;
  T INITIAL_VALUE;
  static T merge(T x, T y);
  void updateNode(int k, T x);
  SegmentTree(int size, T initial_value) {
    n = 1;
    INITIAL_VALUE = initial_value;
    while (n < size) n *= 2;
    data.resize(2 * n - 1, INITIAL_VALUE);
  }
  T getLeaf(int k) { return data[k + n - 1]; }
  void update(int k, T x) {
    k += n - 1;
    updateNode(k, x);
    while (k > 0) {
      k = (k - 1) / 2;
      data[k] = merge(data[k * 2 + 1], data[k * 2 + 2]);
    }
  }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) return INITIAL_VALUE;
    if (a <= l && r <= b)
      return data[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 merge(vl, vr);
    }
  }
  T query(int a, int b) { return query(a, b, 0, 0, n); }
};
template <typename T>
T SegmentTree<T>::merge(T x, T y) {
  return min(x, y);
}
template <typename T>
void SegmentTree<T>::updateNode(int k, T x) {
  data[k] = x;
}
struct UnionFind {
  vector<int> data;
  UnionFind(int sz) : data(sz, -1) {}
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    bool is_union = (x != y);
    if (is_union) {
      if (data[x] > data[y]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return is_union;
  }
  int find(int x) {
    if (data[x] < 0) {
      return x;
    } else {
      data[x] = find(data[x]);
      return data[x];
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -data[find(x)]; }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n;
  ll d;
  cin >> n >> d;
  vector<ll> a(n);
  vector<P> v;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    v.emplace_back(a[i], i);
  }
  sort(v.begin(), v.end());
  vector<vector<ll> > es;
  SegmentTree<P> st1(n, P(INF, -1)), st2(n, P(INF, -1));
  for (int j = 0; j < n; j++) {
    int i = v[j].second;
    ll x = v[j].first;
    P p1 = st1.query(0, i);
    P p2 = st2.query(i + 1, n);
    if (p1.second != -1) {
      p1.first += x + d * i;
    }
    if (p2.second != -1) {
      p2.first += x - d * i;
    }
    if (p1.first <= p2.first) {
      es.push_back({p1.first, i, p1.second});
    } else {
      es.push_back({p2.first, i, p2.second});
    }
    st1.update(i, P(x - d * i, i));
    st2.update(i, P(x + d * i, i));
  }
  for (int i = 0; i < n; i++) {
    st1.update(i, P(INF, -1));
    st2.update(i, P(INF, -1));
  }
  for (int j = n - 1; j >= 0; j--) {
    int i = v[j].second;
    ll x = v[j].first;
    P p1 = st1.query(0, i);
    P p2 = st2.query(i + 1, n);
    if (p1.second != -1) {
      p1.first += x + d * i;
    }
    if (p2.second != -1) {
      p2.first += x - d * i;
    }
    if (p1.first <= p2.first) {
      es.push_back({p1.first, i, p1.second});
    } else {
      es.push_back({p2.first, i, p2.second});
    }
    st1.update(i, P(x - d * i, i));
    st2.update(i, P(x + d * i, i));
  }
  sort(es.begin(), es.end());
  UnionFind uf(n);
  ll min_cost = 0;
  for (vector<ll>& e : es) {
    if (e[1] == -1 || e[2] == -1) continue;
    if (uf.same(e[1], e[2])) continue;
    uf.unite(e[1], e[2]);
    min_cost += e[0];
  }
  cout << min_cost << endl;
  return 0;
}
