Problem:
Score : 600 points

Problem Statement

There are N cities in Republic of AtCoder. The size of the i-th city is A_{i}.
Takahashi would like to build N-1 bidirectional roads connecting two cities so that any city can be reached from any other city by using these roads.

Assume that the cost of building a road connecting the i-th city and the j-th city is |i-j| \times D + A_{i} + A_{j}.
For Takahashi, find the minimum possible total cost to achieve the objective.

Constraints

1 \leq N \leq 2 \times 10^5

1 \leq D \leq 10^9

1 \leq A_{i} \leq 10^9

A_{i} and D are integers.

Input

Input is given from Standard Input in the following format:

N D
A_1 A_2 ... A_N

Output

Print the minimum possible total cost.

Sample Input 1

3 1
1 100 1

Sample Output 1

106

This cost can be achieved by, for example, building roads connecting City 1, 2 and City 1, 3.

Sample Input 2

3 1000
1 100 1

Sample Output 2

2202

Sample Input 3

6 14
25 171 7 1 17 162

Sample Output 3

497

Sample Input 4

12 5
43 94 27 3 69 99 56 25 8 15 46 8

Sample Output 4

658

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;
using ll = int64_t;
using P = pair<ll, ll>;
const ll INF = 5e17;

template <typename T>
class SegmentTree{
    public:
        ll size;
        vector<T> node;
        T identity_ele;  //comp(x, identity_ele) == x
        function<T(T, T)> comp;

        SegmentTree(const vector<T> &v, function<T(T, T)> comp, T identity_ele){
            ll tmp = 1;
            while(tmp < v.size()) tmp = (tmp << 1);
            this->size = tmp;
            this->identity_ele = identity_ele;
            this->comp = comp;
            node.resize(2 * size - 1);
            for(ll i = 0; i < v.size(); i++){
                node[i + size - 1] = v[i];
            }
            for(ll i = size - 2; 0 <= i; i--){
                node[i] = comp(node[i * 2 + 1], node[i * 2 + 2]);
            }
        }

        void update(ll pos, T value){
            pos += size - 1;
            node[pos] = value;
            while(pos > 0){
                pos = (pos - 1) / 2;
                node[pos] = comp(node[2 * pos + 1], node[2 * pos + 2]);
            }
        }

        T query(ll a, ll b){
            return subQuery(a, b, 0, 0, size);
        }

        T subQuery(ll a, ll b, ll k, ll l, ll r){
            if(r <= a || b <= l){
                return identity_ele;
            }else if(a <= l && r <= b){
                return node[k];
            }else{
                T left = subQuery(a, b, k * 2 + 1, l, (l + r) / 2);
                T right = subQuery(a, b, k * 2 + 2, (l + r) / 2, r);
                return comp(left, right);
            }
        }
};

struct E {
    ll f, t, c;
};

class UnionFind{
    public:
        ll size;
        ll *rank;
        ll *parent;

        UnionFind(ll N){
            this->size = N;
            rank = new ll[size];
            parent = new ll[size];
            for(ll i = 0; i < size; ++i){
                rank[i] = 0;
                parent[i] = i;
            }
        }

        ~UnionFind(){
        }

        ll find(ll child){
            return (child == parent[child] ? child : parent[child] = find(parent[child]));
        }

        void unit(ll x, ll y){
            x = find(x); y = find(y);
            if(x != y){
                if(rank[x] > rank[y]){
                    parent[y] = x;
                }else{
                    parent[x] = y;
                    if(rank[x] == rank[y]){
                        ++rank[y];
                    }
                }
            }
        }

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

int main(){
    ll N, D;
    cin >> N >> D;
    vector<P> A;
    for(ll i = 0; i < N; i++){
        ll a;
        cin >> a;
        A.push_back(P(a, i));
    }
    sort(A.begin(), A.end());
    vector<P> init;
    for(ll i = 0; i < N; i++) init.push_back(P(INF, i));
    SegmentTree<P> STL(init, [](P a, P b){ return a.first < b.first ? a : b; }, P(INF, INF));
    SegmentTree<P> STR(init, [](P a, P b){ return a.first < b.first ? a : b; }, P(INF, INF));
    vector<E> edges;
    for(const P &a : A){
        if(a.second != 0){
            P left = STL.query(0, a.second);
            if(left != P(INF, INF)){
                ll cost = left.first + a.second * D + a.first;
                edges.push_back(E{left.second, a.second, cost});
            }
        }
        if(a.second != N - 1){
            P right = STR.query(a.second + 1, N);
            if(right != P(INF, INF)){
                ll cost = right.first - a.second * D + a.first;
                edges.push_back(E{right.second, a.second, cost});
            }
        }
        STL.update(a.second, P(a.first - D * a.second, a.second));
        STR.update(a.second, P(a.first + D * a.second, a.second));
    }
    sort(edges.begin(), edges.end(), [](const E &a, const E &b){ return a.c < b.c; });
    UnionFind UF(N);
    ll ans = 0;
    for(const E &e : edges){
        if(UF.same(e.f, e.t)) continue;
        ans += e.c;
        UF.unit(e.f, e.t);
    }
    cout << ans << endl;
    return 0;
}