#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#define _USE_MATH_DEFINES
#include <cmath>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iomanip>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()

const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
// const int dy[] = {1, 1, 0, -1, -1, -1, 0, 1},
//           dx[] = {0, -1, -1, -1, 0, 1, 1, 1};

struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    cerr << fixed << setprecision(10);
  }
} iosetup;
/*-------------------------------------------------*/
struct UnionFind {
  UnionFind(int n) : data(n, -1) {}

  int root(int ver) { return data[ver] < 0 ? ver : data[ver] = root(data[ver]); }

  void unite(int ver1, int ver2) {
    ver1 = root(ver1);
    ver2 = root(ver2);
    if (ver1 != ver2) {
      if (data[ver1] > data[ver2]) swap(ver1, ver2);
      data[ver1] += data[ver2];
      data[ver2] = ver1;
    }
  }

  bool same(int ver1, int ver2) { return root(ver1) == root(ver2); }

  int size(int ver) { return -data[root(ver)]; }

private:
  vector<int> data;
};

using CostType = long long;
struct Edge {
  int src, dst; CostType cost;
  Edge(int src, int dst, CostType cost = 0) : src(src), dst(dst), cost(cost) {}
  inline bool operator<(const Edge &rhs) const {
    return cost != rhs.cost ? cost < rhs.cost : dst != rhs.dst ? dst < rhs.dst : src < rhs.src;
  }
  inline bool operator<=(const Edge &rhs) const { return cost <= rhs.cost; }
  inline bool operator>(const Edge &rhs) const {
    return cost != rhs.cost ? cost > rhs.cost : dst != rhs.dst ? dst > rhs.dst : src > rhs.src;
  }
  inline bool operator>=(const Edge &rhs) const { return cost >= rhs.cost; }
};

int main() {
  int n; long long d; cin >> n >> d;
  vector<int> a(n); REP(i, n) cin >> a[i];
  vector<Edge> edges;
  function<void(int, int)> rec = [&](int l, int r) {
    if (r - l <= 1) return;
    int mid = (l + r) / 2;
    rec(l, mid);
    rec(mid, r);
    int idx;
    long long mn = LINF;
    FOR(i, mid, r) {
      long long cost = d * (i + 1) + a[i];
      if (cost < mn) {
        mn = cost;
        idx = i;
      }
    }
    FOR(i, l, mid) edges.emplace_back(i, idx, mn + a[i] - d * (i + 1));
    mn = LINF;
    FOR(i, l, mid) {
      long long cost = -d * (i + 1) + a[i];
      if (cost < mn) {
        mn = cost;
        idx = i;
      }
    }
    FOR(i, mid, r) edges.emplace_back(i, idx, mn + a[i] + d * (i + 1));
  };
  rec(0, n);
  sort(ALL(edges));
  long long ans = 0;
  UnionFind uf(n);
  for (const Edge &e : edges) {
    if (!uf.same(e.src, e.dst)) {
      ans += e.cost;
      uf.unite(e.src, e.dst);
    }
  }
  cout << ans << '\n';
  return 0;
}


Measured memory_bytes: 68704