#include <stdio.h>
#include <assert.h>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <array>
#include <vector>
#include <queue>
#include <set>
#include <cmath>
#include <iomanip>
//#include <unordered_map>
//#include <unordered_set>
//#include <boost/container/static_vector.hpp>
//#include <boost/unordered_set.hpp>
//#include <boost/unordered_map.hpp>
//#include <unistd.h>

struct Edge {
    int node1;
    int node2;
    long long cost;
};

class Union_Find {
    public:
    std::vector<int> par;
    Union_Find() {}
    Union_Find(int n){
        par.resize(n, 0);
        for(int i = 0; i < n; i++){
            par[i] = i;
        }
    }

    void simplify(int x) {
        std::vector<int> path;
        while (par[x] != x) {
            path.push_back(x);
            x = par[x];
        }
        for (int p : path) {
            par[p] = x;
        }
    }
    
    int find(int x){
        simplify(x);
        return par[x];
    }
};

const int MAX_N = 200050;
int N;
long long D, A[MAX_N];

int right_path[MAX_N] = {};
int left_path[MAX_N] = {};

Union_Find uf = Union_Find(MAX_N);

//Union_Find uf_c = Union_Find(MAX_N);

long long total_cost = 0;
//long long total_cost_c = 0;

void unite(int x, int y, long long cost){
    x = uf.find(x);
    y = uf.find(y);
    if (x != y) {
        uf.par[y] = x;
        // 改造する時は「根になっているノードの親を変更する」という原則が守られていることに注意。
        total_cost += cost;
    }
}

/*
void unite_c(int x, int y, long long cost){
    x = uf_c.find(x);
    y = uf_c.find(y);
    if (x != y) {
        uf_c.par[y] = x;
        // 改造する時は「根になっているノードの親を変更する」という原則が守られていることに注意。
        total_cost_c += cost;
    }
}
*/

int main(int argc, char **argv) {
    std::cin >> N >> D;
    
    for (int i = 1; i <= N; i++) {
        std::cin >> A[i];
    }

    std::vector<std::pair<int, long long>> right_cand, left_cand;

    for (int i = 1; i <= N; i++) {
        right_cand.push_back(std::pair<int, long long>({i, A[i] + D*i}));
        left_cand.push_back(std::pair<int, long long>({i, A[i] - D*i}));
    }

    std::sort(right_cand.begin(), right_cand.end(),
        [](const std::pair<int, long long>& a, const std::pair<int, long long>& b) { return a.second < b.second; }
    );
    std::sort(left_cand.begin(), left_cand.end(),
        [](const std::pair<int, long long>& a, const std::pair<int, long long>& b) { return a.second < b.second; }
    );

    int begin = 1;
    for (auto pair : right_cand) {
        while (begin < pair.first) {
            right_path[begin] = pair.first;
            begin++;
        }
    }

    begin = N;
    for (auto pair : left_cand) {
        while (pair.first < begin) {
            left_path[begin] = pair.first;
            begin--;
        }
    }
    
    std::vector<Edge> graph;
    int ef_prev = 0;
    for (int i = 1; i <= N; i++) {
        bool is_effective = true;
        if (i < N) {
            Edge e;
            e.node1 = i;
            e.node2 = right_path[i];
            e.cost = D * (right_path[i] - i) + A[i] + A[right_path[i]];
            graph.push_back(e);
            if (A[right_path[i]] + D * (right_path[i] - i) < A[i]) {
                is_effective = false;
            }
        }
        if (1 < i) {
            Edge e;
            e.node1 = i;
            e.node2 = left_path[i];
            e.cost = D * (i - left_path[i]) + A[i] + A[left_path[i]];
            graph.push_back(e);
            if (A[left_path[i]] + D * (i - left_path[i]) < A[i]) {
                is_effective = false;
            }
        }
        if (is_effective) {
            if (ef_prev != 0) {
                Edge e;
                e.node1 = ef_prev;
                e.node2 = i;
                e.cost = D * (i - ef_prev) + A[i] + A[ef_prev];
                graph.push_back(e);
            }
            ef_prev = i;
        }
    }



    std::sort(graph.begin(), graph.end(),
        [](const Edge& a, const Edge& b) { return a.cost < b.cost; }
    );

    for (auto e : graph) {
        unite(e.node1, e.node2, e.cost);
    }

    std::cout << total_cost << std::endl;

    /*
    std::vector<Edge> graph_c;
    for (int i = 1; i <= N; i++) {
        for (int j = i + 1; j <= N; j++) {
            Edge e;
            e.node1 = i;
            e.node2 = j;
            e.cost = D * (j - i) + A[i] + A[j];
            graph_c.push_back(e);
        }
    }
    std::sort(graph_c.begin(), graph_c.end(),
        [](const Edge& a, const Edge& b) { return a.cost < b.cost; }
    );

    for (auto e : graph_c) {
        unite_c(e.node1, e.node2, e.cost);
    }

    std::cout << total_cost_c << std::endl;
    */


    return 0;
}



Measured memory_bytes: 28376