#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pli = pair<ll, int>;
const ll INF = 1e17;
struct RMQ {
  using type = pli;
  static type id() { return make_pair(INF, -1); }
  static type op(const type &l, const type &r) { return min(l, r); }
};
const int PMAX = 2e7;
template <typename M>
class persistent_segment_tree {
  using T = typename M::type;
  struct node {
    T val;
    node *l, *r;
    node() {}
    node(T v) : val(v), l(nullptr), r(nullptr) {}
    void init(T v, node *left, node *right) {
      val = v;
      l = left;
      r = right;
    }
  };
  const int n;
  vector<node> pool;
  int it;
  vector<node *> root;
  int size(int x) {
    int res = 1;
    while (res < x) res <<= 1;
    return res;
  }
  T get(node *p) { return p == nullptr ? M::id() : p->val; }
  node *new_node(T val, node *l = nullptr, node *r = nullptr) {
    pool[it].init(val, l, r);
    return &pool[it++];
  }
  node *fix(node *x, int p, T val, int lb, int ub) {
    if (p < lb || ub <= p) return x;
    if (lb + 1 == ub) return new_node(val);
    if (x == nullptr)
      x = new_node(M::id());
    else
      x = new_node(x->val, x->l, x->r);
    int c = (lb + ub) / 2;
    x->l = fix(x->l, p, val, lb, c);
    x->r = fix(x->r, p, val, c, ub);
    x->val = M::op(get(x->l), get(x->r));
    return x;
  }
  T sub(node *x, int l, int r, int lb, int ub) {
    if (x == nullptr || ub <= l || r <= lb) return M::id();
    if (l <= lb && ub <= r) return x->val;
    int c = (lb + ub) / 2;
    return M::op(sub(x->l, l, r, lb, c), sub(x->r, l, r, c, ub));
  }

 public:
  persistent_segment_tree(int n_) : n(size(n_)), pool(PMAX), it(0) {
    root.push_back(nullptr);
  }
  void update(int p, T val, int rt = -1) {
    if (rt == -1) rt = root.size() - 1;
    assert(0 <= rt && rt < (int)root.size());
    root.push_back(fix(root[rt], p, val, 0, n));
  }
  T find(int l, int r, int rt = -1) {
    if (rt == -1) rt = root.size() - 1;
    assert(0 <= rt && rt < (int)root.size());
    return sub(root[rt], l, r, 0, n);
  }
  int getversion() { return root.size() - 1; }
};
class quick_find {
  vector<int> rt;

 public:
  vector<vector<int>> vs;
  quick_find(int n) : rt(n), vs(n) {
    for (int i = 0; i < n; i++) rt[i] = i, vs[i].push_back(i);
  }
  int find(int a) { return rt[a]; }
  bool same(int a, int b) { return rt[a] == rt[b]; }
  void unite(int a, int b) {
    a = rt[a], b = rt[b];
    if (a == b) return;
    if (vs[a].size() < vs[b].size()) swap(a, b);
    for (auto &v : vs[b]) rt[v] = a;
    copy(vs[b].begin(), vs[b].end(), back_inserter(vs[a]));
  }
  int size(int a) { return vs[rt[a]].size(); }
};
int main() {
  int N;
  ll D;
  cin >> N >> D;
  vector<ll> A(N);
  for (int i = 0; i < N; i++) {
    cin >> A[i];
  }
  ll res = 0;
  quick_find uf(N);
  persistent_segment_tree<RMQ> lst(N), rst(N);
  for (int i = 0; i < N; i++) {
    lst.update(i, make_pair(A[i] - i * D, i));
    rst.update(i, make_pair(A[i] + i * D, i));
  }
  int lv = lst.getversion(), rv = rst.getversion();
  while (uf.size(0) < N) {
    vector<tuple<ll, int, int>> es;
    for (int i = 0; i < N; i++)
      if (uf.find(i) == i) {
        int lver = lv, rver = rv;
        for (auto v : uf.vs[i]) {
          lst.update(v, make_pair(INF, -1), lver);
          lver = lst.getversion();
          rst.update(v, make_pair(INF, -1), rver);
          rver = rst.getversion();
        }
        ll c = INF;
        int to = -1;
        for (auto v : uf.vs[i]) {
          int u = lst.find(0, v, lver).second;
          if (u != -1) {
            ll cost = A[v] + A[u] + abs(v - u) * D;
            if (cost < c) {
              c = cost;
              to = u;
            }
          }
          u = rst.find(v, N, rver).second;
          if (u != -1) {
            ll cost = A[v] + A[u] + abs(v - u) * D;
            if (cost < c) {
              c = cost;
              to = u;
            }
          }
        }
        es.emplace_back(c, i, uf.find(to));
      }
    sort(es.begin(), es.end());
    for (auto e : es) {
      int u, v;
      ll c;
      tie(c, u, v) = e;
      if (uf.same(u, v)) continue;
      uf.unite(u, v);
      res += c;
    }
  }
  cout << res << endl;
  return 0;
}
