#include <stdio.h>
#include <stdlib.h>
#define int long long
#define inf (int)(1e18)

typedef struct {
	int num;
	int val;
}pair;

signed compair(const void *a, const void *b){
	int sub = ((pair *)a)->val - ((pair *)b)->val;
	if(sub < 0){
		return -1;
	}
	else if(sub == 0){
		return 0;
	}
	else{
		return 1;
	}
}


#define seg_tree_valtype pair

typedef struct {
	seg_tree_valtype *dat;
	int n; //要素数
	int N; //要素数以上の最小の2のべき乗
	seg_tree_valtype (*f)(seg_tree_valtype x, seg_tree_valtype y);//演算
	seg_tree_valtype e;//演算の単位元
}seg_tree;

//要素n, 演算f, 単位元eのsegment_treeを作る
seg_tree *make_seg_tree(int n, seg_tree_valtype (*f)(seg_tree_valtype x, seg_tree_valtype y), seg_tree_valtype e){
	seg_tree *t = (seg_tree *)malloc(sizeof(seg_tree));
	int N, i;
	for(N = 1; N < n; N *= 2){}
	t->dat = (seg_tree_valtype *)malloc(sizeof(seg_tree_valtype) * (2 * N - 1));
	for(i = 0; i < 2 * N - 1; i++){
		t->dat[i] = e;
	}
	t->n = n;
	t->N = N;
	t->f = f;
	t->e = e;
	return t;
}

//i番目の要素を返す
seg_tree_valtype look_val(int i, seg_tree *t){
	if(i < 0 || t->n <= i){
		printf("In function 'look_val':\nrefered out of array\n");
	}
	return t->dat[i + t->N - 1];
}

//i番目の値をxに更新する
void update(int i, seg_tree_valtype val, seg_tree *t){
	if(i < 0 || t->n <= i){
		printf("In function 'update':\nrefered out of array\n");
	}
	i += t->N - 1;
	t->dat[i] = val;
	while(i > 0){
		i = (i - 1) / 2;
		t->dat[i] = (t->f)(t->dat[2 * i + 1], t->dat[2 * i + 2]);
	}
}

seg_tree_valtype query_sub(int a, int b, int k, int l, int r, seg_tree *t){
	if(r <= a || b <= l){
		return t->e;
	}
	else if(a <= l && r <= b){
		return t->dat[k];
	}
	else{
		int h = (l + r) / 2;
		seg_tree_valtype vl = query_sub(a, b, 2 * k + 1, l, h, t);
		seg_tree_valtype vr = query_sub(a, b, 2 * k + 2, h, r, t);
		return (t->f)(vl, vr);
	}
}

//[a, b)の区間に対しての演算の結果を返す
seg_tree_valtype query(int a, int b, seg_tree *t){
	if(a < 0 || b < 0 || t->n < a || t->n < b){
		printf("In function 'query':\nrefered out of array\n");
	}
	if(a >= b){
		return t->e;
	}
	else{
		return query_sub(a, b, 0, 0, t->N, t);
	}
}

pair min_pair(pair a, pair b){
	return a.val < b.val ? a : b;
}

typedef struct {
	int u;
	int v;
	int w;
}edge;

signed compare_edge(const void *a, const void *b){
	int sub = ((edge *)a)->w - ((edge *)b)->w;
	if(sub < 0){
		return -1;
	}
	else if(sub == 0){
		return 0;
	}
	else{
		return 1;
	}
}

typedef struct {
	int N;
	int *u;
	int *u_rank;
}union_find;

union_find *make_union_find(int N){
	int i;
	union_find *uf = (union_find *)malloc(sizeof(union_find));
	uf->N = N;
	uf->u = (int *)malloc(sizeof(int) * N);
	uf->u_rank = (int *)malloc(sizeof(int) * N);
	for(i = 0; i < N; i++){
		uf->u[i] = i;
		uf->u_rank[i] = 1;
	}
	return uf;
}

int root_uf(int x, union_find *uf){
	int *u = uf->u;
	if(u[x] == x){
		return x;
	}
	else{
		u[x] = root_uf(u[x], uf);
		return u[x];
	}
}

void combine_uf(int x, int y, union_find *uf){
	int x_root = root_uf(x, uf);
	int y_root = root_uf(y, uf);
	int *u = uf->u;
	int *u_rank = uf->u_rank;
	if(x_root == y_root){
		return;
	}
	else if(u_rank[x_root] < u_rank[y_root]){
		u[x_root] = y_root;
		u_rank[y_root] += u_rank[x_root];
		u_rank[x_root] = 0;
	}
	else{
		u[y_root] = x_root;
		u_rank[x_root] += u_rank[y_root];
		u_rank[y_root] = 0;
	}
}

//xとyが同じ集合に属していれば1を,そうでなければ0を返す
int is_same_union_uf(int x, int y, union_find *uf){
	if(root_uf(x, uf) == root_uf(y, uf)){
		return 1;
	}
	else{
		return 0;
	}
}

//xが属する集合の要素数を返す
int rank_uf(int x, union_find *uf){
	return uf->u_rank[root_uf(x, uf)];
}

signed main(){
	int N, D, i, j;
	scanf("%lld%lld", &N, &D);
	pair *ps = (pair *)malloc(sizeof(pair) * N);
	for(i = 0; i < N; i++){
		ps[i].num = i;
		scanf("%lld", &ps[i].val);
	}
	qsort(ps, N, sizeof(pair), compair);
	seg_tree *tl = make_seg_tree(N, min_pair, (pair){-1, inf});
	seg_tree *tr = make_seg_tree(N, min_pair, (pair){-1, inf});
	pair p;
	edge *es = (edge *)malloc(sizeof(edge) * 2 * N);
	for(i = 0, j = 0; i < N; i++){
//		printf("ps[%lld] = (%lld, %lld)\n", i, ps[i].num, ps[i].val);
		p = query(0, ps[i].num, tl);
//		printf("p = (%lld, %lld)\n", p.num, p.val);
		if(p.num >= 0){
			es[j] = (edge){ps[i].num, p.num, ps[i].val + D * ps[i].num + p.val};
			j++;
		}
		update(ps[i].num, (pair){ps[i].num, ps[i].val - D * ps[i].num}, tl);
		p = query(ps[i].num + 1, N, tr);
//		printf("p = (%lld, %lld)\n", p.num, p.val);
		if(p.num >= 0){
			es[j] = (edge){ps[i].num, p.num, ps[i].val - D * ps[i].num + p.val};
			j++;
		}
		update(ps[i].num, (pair){ps[i].num, ps[i].val + D * ps[i].num}, tr);
/*		int k;
		printf("tl\n");
		for(k = 0; k < N; k++){
			p = query(k, k + 1, tl);
			printf("(%lld, %lld)\n", p.num, p.val);
		}
		printf("tr\n");
		for(k = 0; k < N; k++){
			p = query(k, k + 1, tr);
			printf("(%lld, %lld)\n", p.num, p.val);
		}
*/	}
/*	for(i = 0; i < j; i++){
		printf("es[%lld] = (%lld, %lld, %lld)\n", i, es[i].u, es[i].v, es[i].w);
	}
*/	qsort(es, j, sizeof(edge), compare_edge);
	union_find *uf = make_union_find(N);
	int ans = 0;
	for(i = 0; i < j; i++){
		if(is_same_union_uf(es[i].u, es[i].v, uf) == 0){
			combine_uf(es[i].u, es[i].v, uf);
			ans += es[i].w;
		}
	}
	printf("%lld\n", ans);
	return 0;
}

Measured memory_bytes: 38472