#include <bits/stdc++.h>
#define int long long int
using namespace std;
template<typename T,typename U> using P=pair<T,U>;
template<typename T> using V=vector<T>;
template<typename T>bool chmax(T&a,T b){if(a<b){a=b;return true;}return false;}
template<typename T>bool chmin(T&a,T b){if(a>b){a=b;return true;}return false;}

template<typename T>auto&operator<<(ostream&s,const vector<T>&v){s<<"[";bool a=1;for(auto e:v){s<<(a?"":" ")<<e;a=0;}s<<"]";return s;}
template<typename T,typename U>auto&operator<<(ostream&s,const pair<T,U>&p){s<<"("<<p.first<<","<<p.second<<")";return s;}
template<typename T>auto&operator<<(ostream&s,const set<T>&st){s<<"{";bool a=1;for(auto e:st){s<<(a?"":" ")<<e;a=0;}s<<"}";return s;}
template<typename T,typename U>auto&operator<<(ostream&s,const map<T,U>&m){s<<"{";bool a=1;for(auto e:m){s<<(a?"":" ")<<e.first<<":"<<e.second;a=0;}s<<"}";return s;}
#define DUMP(x) cout<<#x<<" = "<<(x)<<endl
#define COUT(x) cerr<<#x<<" = "; cout<<(x)<<endl

struct edge { int to, cost; };

const int INF = 1e18;
const int MOD = 1e9+7;

template<typename Monoid>
struct SegmentTree {
   using F = function<Monoid(Monoid,Monoid)>;
   int sz;
   vector< Monoid > seg;
   const F f;
   const Monoid M1;
   SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
      sz = 1;
      while(sz < n) sz <<= 1;
      seg.assign(2 * sz, M1);
   }
   void set(int k, const Monoid &x) {
      seg[k + sz] = x;
   }
   void build() {
      for(int k = sz - 1; k > 0; k--) {
         seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
      }
   }
   void update(int k, const Monoid &x) {
      k += sz;
      seg[k] = x;
      while(k >>= 1) {
         seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
      }
   }
   // Monoid query(int a, int b) {
   //    Monoid L = M1, R = M1;
   //    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
   //       if(a & 1) L = f(L, seg[a++]);
   //       if(b & 1) R = f(seg[--b], R);
   //    }
   //    return f(L, R);
   // }

   Monoid query(int a, int b, int k, int l, int r) {
      if (r <= a || b <= l) {
         return M1;
      } else if (a <= l && r <= b) {
         return seg[k];
      } else {
         return f(query(a, b, 2 * k + 0, l, (l + r) / 2),
                  query(a, b, 2 * k + 1, (l + r) / 2, r));
      }
   }
   Monoid query(int a, int b) {
      // return f[a, b).
      return query(a, b, 1, 0, sz);
   }
   Monoid operator[](const int &k) const {
      return seg[k + sz];
   }
};
template<typename T> struct RMQ {
   SegmentTree<T> segt;
   RMQ(int n, const T& inf=INF, const T& init=INF) : segt(n, [](T a,T b){return min(a,b);}, inf) {
      for (int i = 0; i < n; i++) segt.set(i,init);
      segt.build();
   }
   void update(int i, const T& x) { segt.update(i, x); }
   T query(int a, int b) { return segt.query(a, b); }
   // int iquery(int a, int b) { return segt.iquery(a, b); }
};

int prim(const vector< vector<edge> >& G, int s=0)
{
   int sum = 0;
   vector<bool> used(G.size(), false);
   priority_queue<P<int,int>, vector<P<int,int>>, greater<P<int,int>> > que;
   que.push(make_pair(0, s));
   while (!que.empty()) {
      int cost = que.top().first;
      int from = que.top().second;
      que.pop();
      if (used[from]) continue;
      used[from] = true;
      sum += cost;
      for (int i = 0; i < G[from].size(); i++) {
         edge e = G[from][i];
         if (!used[e.to]) {
            que.push(make_pair(e.cost, e.to));
         }
      }
   }
   return sum;
}


signed main()
{
   int N, D; cin >> N >> D;
   V<int> A(N);
   for (int i = 0; i < N; i++) {
      cin >> A[i];
   }

   V<P<int,int>> p(N);
   for (int i = 0; i < N; i++) {
      p[i] = { A[i], i };
   }
   sort(p.begin(), p.end());

   RMQ<P<int,int>> L(N, {INF,-1}, {INF,-1}), R(N, {INF,-1}, {INF,-1});
   V<V<edge>> G(N);
   for (int i = 0; i < N; i++) {
      int idx = p[i].second;
      int l = L.query(0, idx).second;
      if (l != -1) {
         int cost = (idx-l) * D + A[idx] + A[l];
         G[idx].push_back({ l, cost });
         G[l].push_back({ idx, cost });
      }
      int r = R.query(idx+1, N).second;
      if (r != -1) {
         int cost = (r-idx) * D + A[idx] + A[r];
         G[idx].push_back({ r, cost });
         G[r].push_back({ idx, cost });
      }

      L.update(idx, {A[idx] - D * idx, idx});
      R.update(idx, {A[idx] + D * idx, idx});
   }

   int sum = prim(G);
   cout << sum << endl;

   return 0;
}

Measured memory_bytes: 53616