#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <cmath>
#include <map>
#include <utility>

#define reps(i,s,n) for(int (i) = (s); (i) < (n); (i)++)
#define rep(i,n) reps(i,0,n)
using namespace std;
using ll = long long;
const ll INF = 1e15;

class Unionfind{
public:
    vector<int> par,rank;

    Unionfind(int n){
        par.resize(n);
        rank.resize(n);
        rep(i,n){
            par[i] = i;
            rank[i] = 0;
        }
    }

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

    void unite(int x,int y){
        x = find(x);
        y = find(y);
        if(x == y) return;

        if(rank[x] < rank[y]){
            par[x] = y;
        }else{
            par[y] = x;
            if(rank[x] == rank[y]) rank[x]++;
        }
    }

    bool same(int x,int y){
        return find(x) == find(y);
    }
};

struct RMQ{
    vector< pair<ll,int> > node;
    int n=1;

    void init(int x){
        while(n < x){
            n *= 2;
        }
        node.resize(4*n,{1000000000000000,-1});
    }

    void update(int s,ll x){
        int i = s + n - 1;

        node[i].first = x;
        node[i].second = s;
        
        while(i > 0){
            i = (i-1)/2;
            node[i].first = min(node[2*i+1].first,node[2*i+2].first);
            if(node[2*i+1].first > node[2*i+2].first)
                node[i].second = node[2*i+2].second; 
            else 
                node[i].second = node[2*i+1].second; 
        }
    }
    
    pair<ll,int> getMin(int a, int b){
        return getMin(a,b,0,0,n-1);
    }

    pair<ll,int> getMin(int a,int b,int k, int l, int r){
        if(r < a || b < l) return make_pair<ll,int>(1e15,-1);
        if(a <= l && r <= b){ 
            return node[k];
        }
        else{
            pair<ll,int> vl = getMin(a,b,2*k+1,l,(l+r)/2);
            pair<ll,int> vr = getMin(a,b,2*k+2,(l+r)/2+1,r);
            
            if(vl.first > vr.first) return vr;
            return vl;
        }
    }

};


struct edge { int u,v; ll cost;};
bool comp(const edge& e1, const edge& e2){
    return e1.cost < e2.cost;
}

bool comp2(const pair<ll,int>& p1, const pair<ll,int>& p2){
    return p1.first > p2.first;
}

vector<edge> es;

int main(){
    int n;
    ll d,tmp;
    cin >> n >> d;

    if(n <= 1) {
        cout << "0" << endl;
        return 0;
    }
    RMQ seg,seg2;
    seg.init(n);
    seg2.init(n);
    Unionfind uf(n);
    vector<pair<ll,int> > A(n);
    rep(i,n){
        cin >> tmp;
        A[i] = {tmp,i};
        seg.update(i,tmp+i*d);
        seg2.update(i,tmp+(n-i-1)*d);
    }
    sort(A.begin(),A.end(),comp2);

    rep(i,n){
        if(A[i].second < n-1 && 
                    seg.getMin(A[i].second+1,n-1).second >= 0){
        es.push_back({A[i].second ,
                    seg.getMin(A[i].second+1,n-1).second,
                    seg.getMin(A[i].second+1,n-1).first + A[i].first - (A[i].second)*d  });
        }
        if(A[i].second > 0 && 
                    seg.getMin(0,A[i].second-1).second >= 0){
        es.push_back({A[i].second ,
                    seg2.getMin(0,A[i].second-1).second,
                    seg2.getMin(0,A[i].second-1).first + A[i].first - (n-A[i].second-1) * d});
        }
        seg.update(A[i].second,INF);
        seg2.update(A[i].second,INF);
    }

    sort(es.begin(),es.end(),comp);
    ll res = 0;

    rep(i,es.size()){
        edge e = es[i];
        if(!uf.same(e.u,e.v)){
            uf.unite(e.u,e.v);
            res += e.cost;
        }
    }

    cout << res << endl;
}

Measured memory_bytes: 48108