#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); }
};


struct UnionFind
{
   vector<int> par, myrank;
   UnionFind(int n) {
      par.resize(n);
      myrank.resize(n, 0);
      for (int i = 0; i < n; i++) par[i] = i;
   }
   int root(int x) {
      if (par[x] == x) return x;
      return par[x] = root(par[x]);
   }
   void merge(int x, int y) {
      x = root(x);
      y = root(y);
      if (x == y) return;
      if (myrank[x] < myrank[y]) {
         par[x] = y;
      } else {
         par[y] = x;
         if(myrank[x] == myrank[y]) myrank[x]++;
      }
   }
   bool issame(int x, int y) {
      return root(x) == root(y);
   }
};

struct edge { int from, to; int cost; };
bool operator<(const edge &edge1, const edge &edge2) { return edge1.cost < edge2.cost; };
int kruskal(const vector<edge>& E, int N) {
   UnionFind uni(N);
   vector<edge> E_tmp(E.size());
   copy(E.begin(), E.end(), E_tmp.begin());
   sort(E_tmp.begin(), E_tmp.end());
   int sum = 0;
   for(int i = 0; i < E_tmp.size(); i++) {
      edge e = E_tmp[i];
      if (!uni.issame(e.from, e.to)) {
         uni.merge(e.from, e.to);
         sum += e.cost;
      }
   }
   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<edge> E;
   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];
         E.push_back({ idx, l, cost });
      }
      int r = R.query(idx+1, N).second;
      if (r != -1) {
         int cost = (r-idx) * D + A[idx] + A[r];
         E.push_back({ idx, r, cost });
      }

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

   for (int i = 0; i < N; i++) {
   }

   int sum = kruskal(E, N);
   cout << sum << endl;

   return 0;
}


Measured memory_bytes: 45032