#include <bits/stdc++.h>
using namespace std;
template <class T>
using reversed_priority_queue = priority_queue<T, vector<T>, greater<T> >;
struct UnionFind {
  vector<int> node;
  UnionFind(int n) : node(n, -1) {}
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (node[y] < node[x]) swap(x, y);
      node[x] += node[y];
      node[y] = x;
    }
    return x != y;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int root(int x) { return node[x] < 0 ? x : node[x] = root(node[x]); }
  int size(int x) { return -node[root(x)]; }
};
long long N, D;
long long A[200010];
int main() {
  cin >> N >> D;
  for (int i = 0; i < N; i++) cin >> A[i];
  vector<vector<long long> > edge;
  for (int i = 0; i < N - 1; i++)
    edge.push_back({D + A[i] + A[i + 1], i, i + 1});
  vector<pair<long long, long long> > v;
  for (int i = 0; i < N; i++) v.push_back(make_pair(A[i], i));
  sort(v.begin(), v.end());
  for (int i = 0; i < N - 1; i++) {
    long long d = abs(v[i].second - v[i + 1].second) * D;
    long long sum = v[i].first + v[i + 1].first;
    edge.push_back({d + sum, v[i].second, v[i + 1].second});
  }
  long long ans = 0;
  sort(edge.begin(), edge.end());
  UnionFind inst(200010);
  for (int i = 0; i < edge.size(); i++) {
    long long cost = edge[i][0];
    int a = (int)edge[i][1];
    int b = (int)edge[i][2];
    if (!inst.same(a, b)) {
      inst.unite(a, b);
      ans += cost;
    }
  }
  cout << ans << endl;
  return 0;
}
