#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
template <class T>
using vec = vector<T>;
template <class T>
using vvec = vector<vec<T>>;
constexpr long long INF = 1LL << 60;
constexpr int INF_INT = 1 << 25;
constexpr long long MOD = (ll)1e9 + 7;
using ld = long double;
static const ld pi = 3.141592653589793L;
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
struct Edge {
  ll to, rev;
  long double cap;
  Edge(ll _to, long double _cap, ll _rev) {
    to = _to;
    cap = _cap;
    rev = _rev;
  }
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;
void add_edge(Graph &G, ll from, ll to, long double cap, bool revFlag,
              long double revCap) {
  G[from].push_back(Edge(to, cap, (ll)G[to].size()));
  if (revFlag) G[to].push_back(Edge(from, revCap, (ll)G[from].size() - 1));
}
template <typename T, typename F>
class SegmentTree {
 private:
  T e;
  F op;
  ll n;
  vector<T> dat;

 public:
  SegmentTree(F f, T _e, vector<T> v) : op(f), e(_e) {
    int _n = v.size();
    n = 1;
    while (n < _n) n *= 2;
    dat.resize(2 * n - 1, e);
    for (int(i) = (int)(0); i < (int)(_n); ++i) dat[n + i - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      dat[i] = op(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  SegmentTree(F f, T _e, int _n) : op(f), e(_e) {
    n = 1;
    while (n < _n) n *= 2;
    dat.resize(2 * n - 1, e);
    for (int i = n - 2; i >= 0; i--)
      dat[i] = op(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  void update(int i, T x) {
    i += n - 1;
    dat[i] = x;
    while (i > 0) {
      i = (i - 1) / 2;
      dat[i] = op(dat[i * 2 + 1], dat[i * 2 + 2]);
    }
  }
  T query(int l, int r) {
    T left = e, right = e;
    l += n - 1;
    r += n - 1;
    while (l < r) {
      if ((l & 1) == 0) left = op(left, dat[l]);
      if ((r & 1) == 0) right = op(dat[r - 1], right);
      l = l / 2;
      r = (r - 1) / 2;
    }
    return op(left, right);
  }
};
class UnionFind {
  vector<int> data;
  int num;

 public:
  UnionFind(int size) : data(size, -1), num(size) {}
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
      num--;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
  int numSet() { return num; }
};
void solve() {
  ll n, d;
  cin >> n >> d;
  vec<ll> a(n);
  for (int(i) = (int)(0); i < (int)(n); ++i) {
    cin >> a[i];
  }
  vec<pair<ll, ll>> al(n), ar(n);
  for (int(i) = (int)(0); i < (int)(n); ++i) {
    al[i] = {a[i] + d * (n - 1 - i), i};
    ar[i] = {a[i] + d * i, i};
  }
  auto op = [](pair<ll, ll> a, pair<ll, ll> b) { return min(a, b); };
  SegmentTree<pair<ll, ll>, decltype(op)> segl(op, {INF, INF}, al);
  SegmentTree<pair<ll, ll>, decltype(op)> segr(op, {INF, INF}, ar);
  vec<tuple<ll, ll, ll>> es;
  for (int(i) = (int)(0); i < (int)(n); ++i) {
    if (i > 0) {
      auto bl = segl.query(0, i);
      es.push_back({bl.first + a[i] - (n - 1 - i) * d, bl.second, i});
    }
    if (i < n - 1) {
      auto br = segr.query(i + 1, n);
      es.push_back({br.first + a[i] - i * d, br.second, i});
    }
  }
  sort((es).begin(), (es).end());
  UnionFind uni(n);
  ll ans = 0;
  for (auto [cap, u, v] : es) {
    if (uni.unionSet(u, v)) {
      ans += cap;
    }
  }
  cout << ans << '\n';
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  solve();
  return 0;
}
