#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9;
const long long int linf = 1LL << 50;
const double EPS = 1e-10;
const int mod = 1e9 + 7;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (auto &v : vec) is >> v;
  return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) {
    os << vec[i];
    if (i + 1 != vec.size()) os << " ";
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const set<T> &st) {
  for (auto itr = st.begin(); itr != st.end(); ++itr) {
    os << *itr;
    auto titr = itr;
    if (++titr != st.end()) os << " ";
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_set<T> &st) {
  for (auto itr = st.begin(); itr != st.end(); ++itr) {
    os << *itr;
    auto titr = itr;
    if (++titr != st.end()) os << " ";
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const multiset<T> &st) {
  for (auto itr = st.begin(); itr != st.end(); ++itr) {
    os << *itr;
    auto titr = itr;
    if (++titr != st.end()) os << " ";
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_multiset<T> &st) {
  for (auto itr = st.begin(); itr != st.end(); ++itr) {
    os << *itr;
    auto titr = itr;
    if (++titr != st.end()) os << " ";
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const map<T1, T2> &mp) {
  for (auto itr = mp.begin(); itr != mp.end(); ++itr) {
    os << itr->first << ":" << itr->second;
    auto titr = itr;
    if (++titr != mp.end()) os << " ";
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const unordered_map<T1, T2> &mp) {
  for (auto itr = mp.begin(); itr != mp.end(); ++itr) {
    os << itr->first << ":" << itr->second;
    auto titr = itr;
    if (++titr != mp.end()) os << " ";
  }
  return os;
}
typedef struct UnionFind_ {
  vector<int> par;
  vector<int> rank_;
  UnionFind_(int n) : rank_(n, 0) {
    for (int i = 0; i < n; i++) par.push_back(i);
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }
  bool same(int x, int y) {
    if (find(x) == find(y))
      return true;
    else
      return false;
  }
  bool unite(int x, int y) {
    int xp = find(x);
    int yp = find(y);
    if (xp == yp) return false;
    if (rank_[xp] > rank_[yp])
      par[yp] = xp;
    else if (rank_[xp] < rank_[yp])
      par[xp] = yp;
    else {
      par[yp] = xp;
      rank_[xp]++;
    }
    return true;
  }
} UnionFind;
template <typename T>
struct edge {
  int from;
  int to;
  T cost;
};
template <typename T>
bool comp(const edge<T> &a, const edge<T> &b) {
  return a.cost < b.cost;
}
template <typename T>
struct Graph {
  int n;
  vector<edge<T>> es;
  Graph(int n_) { n = n_; }
  void adde(int from, int to, T cost) {
    es.push_back((edge<T>){from, to, cost});
  }
  T kruskal() {
    T res = 0;
    UnionFind uf(n);
    sort(es.begin(), es.end(), comp<T>);
    for (auto e : es) {
      int from = e.from;
      int to = e.to;
      T cost = e.cost;
      if (uf.same(from, to)) continue;
      res += cost;
      uf.unite(from, to);
    }
    return res;
  }
};
using GraphI = Graph<int>;
template <typename T, typename E>
struct SegmentTree_ {
  function<T(T, T)> f;
  function<T(T, E)> g;
  int n;
  T def;
  vector<T> vec;
  SegmentTree_() {}
  SegmentTree_(int n_, function<T(T, T)> f_, function<T(T, E)> g_, T def_,
               vector<T> v = vector<T>()) {
    f = f_;
    g = g_;
    def = def_;
    n = 1;
    while (n < n_) {
      n *= 2;
    }
    vec = vector<T>(2 * n - 1, def);
    for (int i = 0; i < v.size(); i++) {
      vec[i + n - 1] = v[i];
    }
    for (int i = n - 2; i >= 0; i--) {
      vec[i] = f(vec[2 * i + 1], vec[2 * i + 2]);
    }
  }
  void update(int k, E val) {
    k = k + n - 1;
    vec[k] = g(vec[k], val);
    while (k > 0) {
      k = (k - 1) / 2;
      vec[k] = f(vec[2 * k + 1], vec[2 * k + 2]);
    }
  }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) return def;
    if (a <= l && r <= b) return vec[k];
    T ld = query(a, b, 2 * k + 1, l, (l + r) / 2);
    T rd = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return f(ld, rd);
  }
  T query(int a, int b) { return query(a, b, 0, 0, n); }
};
template <typename T, typename E>
using SegmentTree = struct SegmentTree_<T, E>;
using SegmentTreeI = SegmentTree<int, int>;
using SegmentTreeL = SegmentTree<long long, long long>;
int main(int argc, char const *argv[]) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n;
  long long int d;
  cin >> n >> d;
  vector<long long int> a(n);
  cin >> a;
  SegmentTree<pair<long long int, int>, pair<long long int, int>> seg =
      SegmentTree<pair<long long int, int>, pair<long long int, int>>(
          n,
          [](pair<long long int, int> a, pair<long long int, int> b) {
            return a.first < b.first ? a : b;
          },
          [](pair<long long int, int> a, pair<long long int, int> b) {
            return b;
          },
          make_pair(linf, -1), vector<pair<long long int, int>>());
  Graph<long long int> graph(n);
  for (int i = (0); i < (n); ++i) {
    if (i > 0) {
      auto p = seg.query(0, i);
      graph.adde(i, p.second,
                 (long long int)(i - p.second) * d + a[i] + a[p.second]);
      graph.adde(p.second, i,
                 (long long int)(i - p.second) * d + a[i] + a[p.second]);
    }
    seg.update(i, make_pair(-(long long int)(i + 1) * d + a[i], i));
  }
  seg = SegmentTree<pair<long long int, int>, pair<long long int, int>>(
      n,
      [](pair<long long int, int> a, pair<long long int, int> b) {
        return a.first < b.first ? a : b;
      },
      [](pair<long long int, int> a, pair<long long int, int> b) { return b; },
      make_pair(linf, -1), vector<pair<long long int, int>>());
  for (int i = ((int)(n)-1); i >= 0; i--) {
    if (i < n - 1) {
      auto p = seg.query(i + 1, n);
      graph.adde(i, p.second,
                 (long long int)(p.second - i) * d + a[i] + a[p.second]);
      graph.adde(p.second, i,
                 (long long int)(p.second - i) * d + a[i] + a[p.second]);
    }
    seg.update(i, make_pair((long long int)(i + 1) * d + a[i], i));
  }
  cout << graph.kruskal() << endl;
  return 0;
}
