//Segment Tree
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define ll long long
#define ls(x) x << 1
#define rs(x) x << 1 | 1
#define rep(i, a, b) for(int i = a; i <= b; i++)
void read(int &x) {
    x = 0; int flag = 1; char ch = ' ';
    while(ch < '0' || ch > '9') { if(ch == '-') flag = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    x *= flag;
}
void read(ll &x) {
    x = 0; int flag = 1; char ch = ' ';
    while(ch < '0' || ch > '9') { if(ch == '-') flag = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    x *= flag;
}
using namespace std;
const ll inf = 1e18;
const int maxn = 200010;
int n;
ll d, a[maxn];
struct node {
    int pos; 
    ll val;
    node(){}
    node(int a, ll b) { pos = a, val = b; }
    bool operator < (const node & a) const { return val < a.val; }
};
struct Segment_Tree_1 {
//0 - A_i-D*i   1 - A_i+D*i
    node tree[maxn << 2][2];
    void build(int p, int l, int r) {
        tree[p][0] = tree[p][1] = node(l, inf);
        if(l == r) return;
        int mid = (l + r) >> 1;
        build(ls(p), l, mid), build(rs(p), mid + 1, r);
    }
    void update(int p, int l, int r, int pos, node x, int opt) {
        if(l == r) { tree[p][opt] = x; return; }
        int mid = (l + r) >> 1;
        if(pos <= mid) update(ls(p), l, mid, pos, x, opt);
            else update(rs(p), mid + 1, r, pos, x, opt);
        tree[p][opt] = min(tree[ls(p)][opt], tree[rs(p)][opt]);
    }
    node query(int p, int l, int r, int ql, int qr, int opt) {
        if(ql <= l && r <= qr) return tree[p][opt];
        int mid = (l + r) >> 1;
        if(ql > mid) return query(rs(p), mid + 1, r, ql, qr, opt);
        else if(qr <= mid) return query(ls(p), l, mid, ql, qr, opt);
        else return min(query(ls(p), l, mid, ql, qr, opt), query(rs(p), mid + 1, r, ql, qr, opt));
    }
} seg1, seg2;
//seg1 未加入  seg2 已加入
struct Segment_Tree_2 {
    node tree[maxn << 2];
    void build(int p, int l, int r) {
        tree[p] = node(l, inf);
        if(l == r) return;
        int mid = (l + r) >> 1;
        build(ls(p), l, mid), build(rs(p), mid + 1, r);        
    }
    void push_up(int p, int l, int r) {
        int mid = (l + r) >> 1;
        tree[p] = min(tree[ls(p)], tree[rs(p)]);
        node x = seg1.tree[ls(p)][0], y = seg2.tree[rs(p)][1];
        tree[p] = min(tree[p], node(x.pos, x.val + y.val));
        x = seg1.tree[rs(p)][1], y = seg2.tree[ls(p)][0];
        tree[p] = min(tree[p], node(x.pos, x.val + y.val));
    }
    void update(int p, int l, int r, int x) {
        if(l == r) { tree[p].val = inf; return; }
        int mid = (l + r) >> 1;
        if(x <= mid) update(ls(p), l, mid, x);
            else update(rs(p), mid + 1, r, x);
        push_up(p, l, r);
    }
} seg3;
int main()
{
    read(n), read(d);
    if(n == 0) { puts("0"); return 0; }
    rep(i, 1, n) read(a[i]);
    seg1.build(1, 1, n);
    seg2.build(1, 1, n);
    seg3.build(1, 1, n);
    rep(i, 2, n) {
        seg1.update(1, 1, n, i, node(i, a[i] - i * d), 0);
        seg1.update(1, 1, n, i, node(i, a[i] + i * d), 1);
    }
    seg2.update(1, 1, n, 1, node(1, a[1] - d), 0);
    seg2.update(1, 1, n, 1, node(1, a[1] + d), 1);
    seg3.update(1, 1, n, 1);
    ll ans = 0;
    rep(i, 1, n - 1) {
        ans += seg3.tree[1].val;
        int tmp = seg3.tree[1].pos;
        seg1.update(1, 1, n, tmp, node(tmp, inf), 0);
        seg1.update(1, 1, n, tmp, node(tmp, inf), 1);
        seg2.update(1, 1, n, tmp, node(tmp, a[tmp] - tmp * d), 0);
        seg2.update(1, 1, n, tmp, node(tmp, a[tmp] + tmp * d), 1);
        seg3.update(1, 1, n, tmp);
    }
    printf("%lld\n", ans);
    return 0;
}

Measured memory_bytes: 50048