#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
using P   = pair<ll, ll>;
using mat = vector<vector<ll>>;

void IOS() { ios::sync_with_stdio(false), cin.tie(0); }

const ll INF = 1e16;
const ll MOD = 1e9 + 7;
const ld EPS = 1e-12;

template <typename T>
void dump(T x) { cout << x << endl; }
void dumpf(ld x, int t) { cout << setprecision(t) << fixed << x << endl; }
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
	fill((T *)array, (T *)(array + N), val);
}
inline ll mod(ll a, ll b) {
	if (a > 0) return a % b;
	if (a % b == 0) return 0;
	ll x = -a / b + 1;
	a += x * b;
	return a % b;
}
ll gcd(ll a, ll b) {
	if (b == 0) return a;
	return gcd(b, a % b);
}

// ll dx[4] = {1, 0, -1, 0};
// ll dy[4] = {0, 1, 0, -1};

struct edge {
	ll from, to, cost;
	bool operator<(edge &e) {
		return (cost < e.cost);
	}
};

template <class Monoid>
class SegTree {
	using OP = std::function<Monoid(Monoid, Monoid)>;

  private:
	int n;
	std::vector<Monoid> dat;
	OP op;
	Monoid e;

  public:
	SegTree(int n_, OP op, Monoid e) : op(op), e(e) {
		n = 1;
		while (n < n_) {
			n *= 2;
		}
		dat.resize(2 * n);
		for (int i = 0; i < 2 * n - 1; i++) {
			dat[i] = e;
		}
	}
	void update(int k, Monoid v) {
		k += n - 1;
		dat[k] = v;
		while (k > 0) {
			k	  = (k - 1) / 2;
			dat[k] = op(dat[2 * k + 1], dat[2 * k + 2]);
		}
	}
	Monoid querySub(int a, int b) const {
		Monoid left  = e;
		Monoid right = e;
		a += n - 1;
		b += n - 1;
		while (a < b) {
			if ((a & 1) == 0) {
				left = op(left, dat[a]);
			}
			if ((b & 1) == 0) {
				right = op(dat[b - 1], right);
			}
			a = a / 2;
			b = (b - 1) / 2;
		}
		return op(left, right);
	}
	Monoid query(int a, int b) const { return querySub(a, b + 1); }
};

struct UnionFind {
  private:
	std::vector<int> rank, par, col;
	int n_;

  public:
	UnionFind(int n) : n_(n) {
		rank.resize(n, 1);
		par.resize(n);
		for (int i = 0; i < n; ++i) {
			par[i] = i;
		}
		col.resize(n, 1);
	}
	int root(int i) {
		while (par[i] != i) {
			i = par[i];
		}
		return i;
	}
	bool isSame(int x, int y) { return root(x) == root(y); }
	void unite(int x, int y) {
		if (isSame(x, y)) return;
		x = root(x), y = root(y);
		if (rank[x] < rank[y]) {
			par[x] = y;
			col[y] += col[x];
		} else {
			if (rank[x] == rank[y]) rank[x]++;
			par[y] = x;
			col[x] += col[y];
		}
	}
	int cnt(int x) {
		x = root(x);
		return col[x];
	}
};

ll a[214514];

signed main() {
	IOS();
	ll n, d;
	cin >> n >> d;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	vector<edge> s;
	P inf = P(INF, INF);

	function<P(P, P)> f = [](P a, P b) { return min(a, b); };
	SegTree<P> sg1(n + 1, f, inf), sg2(n + 1, f, inf);
	for (int i = 1; i <= n; i++) {
		P tmp = sg1.query(1, i);
		edge e;
		e.cost = a[i] + i * d + tmp.first;
		e.from = i;
		e.to   = tmp.second;
		if (i != 1) s.push_back(e);
		sg1.update(i, P(a[i] - i * d, i));
	}
	for (int i = n; i >= 1; i--) {
		P tmp = sg2.query(i, n);
		edge e;
		e.from = i;
		e.to   = tmp.second;
		e.cost = a[i] - i * d + tmp.first;
		if (i != n) s.push_back(e);
		sg2.update(i, P(a[i] + i * d, i));
	}
	sort(s.begin(), s.end());

	ll ans = 0;
	UnionFind uf(n + 1);
	for (int i = 0; i < s.size(); i++) {
		//cout << s[i].from << " " << s[i].to << " " << s[i].cost << endl;
		if (!uf.isSame(s[i].from, s[i].to)) {
			ans += s[i].cost;
			uf.unite(s[i].from, s[i].to);
		}
	}
	dump(ans);
	return 0;
}