#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define ull unsigned long long
#define db double
#define pb push_back
#define ppb pop_back
#define all(x) (x).begin(), (x).end()

template <typename T>
using pr = array <T, 3>;

template <typename T>
using ord_set = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 200003;
int n, sz[N], par[N];
ll d, a[N];
vector <pr <ll> > cand;

void rec(int l, int r) {
	if (l >= r) {
		return;
	}
	int m = l + r >> 1;
	int L = -1, R = -1;
	for (int i = l; i <= m; i++) {
		if (L == -1 || a[i] - i * d < a[L] - L * d) {
			L = i;
		}
	}
	for (int i = m + 1; i <= r; i++) {
		cand.pb({a[L] + a[i] + (i - L) * d, L, i});
		if (R == -1 || a[i] + i * d < a[R] + R * d) {
			R = i;
		}
	}
	for (int i = l; i <= m; i++) {
		cand.pb({a[R] + a[i] + (R - i) * d, i, R});
	}
	rec(l, m);
	rec(m + 1, r);
}

void make_set(int x) {
	par[x] = x;
	sz[x] = 1;
}

int find_set(int x) {
	if (x == par[x]) {
		return x;
	}
	return par[x] = find_set(par[x]);
}

bool union_set(int x, int y) {
	x = find_set(x), y = find_set(y);
	if (x == y) {
		return false;
	}
	if (sz[x] < sz[y]) {
		swap(x, y);
	}
	par[y] = x;
	sz[x] += sz[y];
	return true;
}

int main() {
	ios_base::sync_with_stdio(false), cin.tie(NULL);
	#ifdef LOCAL
		freopen("input.txt", "r", stdin);
	#endif
	
	cin >> n >> d;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	rec(1, n);
	sort(all(cand));
	ll ans = 0;
	for (int i = 1; i <= n; i++) {
		make_set(i);
	}
	for (auto i : cand) {
		int w = i[0], x = i[1], y = i[2];
		if (union_set(x, y)) {
			ans += w;
		}
	}
	cout << ans;
}
