#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class Monoid>
struct RMQ {
  const Monoid INF;
  int SIZE_R;
  vector<pair<Monoid, int> > dat;
  RMQ(int n, const Monoid &inf) : INF(inf) { init(n); }
  void init(int n) {
    SIZE_R = 1;
    while (SIZE_R < n) SIZE_R *= 2;
    dat.assign(SIZE_R * 2, pair<Monoid, int>(INF, -1));
  }
  void set(int a, const Monoid &v) { dat[a + SIZE_R] = make_pair(v, a); }
  void build() {
    for (int k = SIZE_R - 1; k > 0; --k) {
      dat[k] = min(dat[k * 2], dat[k * 2 + 1]);
    }
  }
  void update(int a, const Monoid &v) {
    int k = a + SIZE_R;
    dat[k] = make_pair(v, a);
    while (k >>= 1) dat[k] = min(dat[k * 2], dat[k * 2 + 1]);
  }
  pair<Monoid, int> get(int a, int b) {
    pair<Monoid, int> vleft = make_pair(INF, -1), vright = make_pair(INF, -1);
    for (int left = a + SIZE_R, right = b + SIZE_R; left < right;
         left >>= 1, right >>= 1) {
      if (left & 1) vleft = min(vleft, dat[left++]);
      if (right & 1) vright = min(dat[--right], vright);
    }
    return min(vleft, vright);
  }
  inline Monoid operator[](int a) { return dat[a + SIZE_R].first; }
  void print() {
    for (int i = 0; i < SIZE_R; ++i) {
      Monoid val = (*this)[i];
      if (val < INF)
        cout << val;
      else
        cout << "INF";
      if (i != SIZE_R - 1) cout << ",";
    }
    cout << endl;
  }
};
struct UnionFind {
  vector<int> par;
  UnionFind(int n) : par(n, -1) {}
  void init(int n) { par.assign(n, -1); }
  int root(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = root(par[x]);
  }
  bool issame(int x, int y) { return root(x) == root(y); }
  bool merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (par[x] > par[y]) swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }
  int size(int x) { return -par[root(x)]; }
};
using pint = pair<int, int>;
using Edge = pair<long long, pint>;
int N;
long long D;
vector<pair<long long, int> > A;
int main() {
  cin >> N >> D;
  A.resize(N);
  RMQ<long long> left(N, 1LL << 60), right(N, 1LL << 60);
  for (int i = 0; i < N; ++i) {
    cin >> A[i].first, A[i].second = i;
    left.set(i, A[i].first - D * i);
    right.set(i, A[i].first + D * i);
  }
  left.build(), right.build();
  sort(A.begin(), A.end(), greater<pair<long long, int> >());
  vector<Edge> edges;
  for (int i = 0; i < N; ++i) {
    int p = A[i].second;
    auto le = left.get(0, p);
    auto ri = right.get(p + 1, N);
    edges.push_back(Edge(A[i].first + D * p + le.first, pint(p, le.second)));
    edges.push_back(Edge(A[i].first - D * p + ri.first, pint(p, ri.second)));
    left.update(p, 1LL << 60);
    right.update(p, 1LL << 60);
  }
  UnionFind uf(N);
  sort(edges.begin(), edges.end());
  long long res = 0;
  for (auto e : edges) {
    long long w = e.first;
    int u = e.second.first, v = e.second.second;
    if (uf.issame(u, v)) continue;
    res += w;
    uf.merge(u, v);
  }
  cout << res << endl;
}
