#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
const int INF = (int)((1LL << 31) - 1);
template <typename E, typename R>
class SegmentTree {
 public:
  SegmentTree(const int _n, const E inf, R (*f)(E, E)) : f(f), inf(inf) {
    n = 1;
    while (n < _n) n *= 2;
    data.resize(2 * n, inf);
  }
  void update(int k, E a) {
    k += n - 1;
    data[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      data[k] = (*f)(data[k * 2 + 1], data[k * 2 + 2]);
    }
  }
  R query(int a, int b) { return query(a, b, 0, 0, n); }

 private:
  int n;
  R (*f)(E, E);
  const E inf;
  vector<E> data;
  R query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return inf;
    }
    if (a <= l && r <= b) {
      return data[k];
    } else {
      R vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      R vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return (*f)(vl, vr);
    }
  }
};
auto compare = [](const pair<int, int> &x, const pair<int, int> &y) {
  return x.second > y.second;
};
typedef priority_queue<pair<int, int>, vector<pair<int, int>>,
                       decltype(compare)>
    PriorityQueue;
vector<vector<pair<int, int>>> edges;
vector<bool> visited;
long long solve(PriorityQueue q) {
  long long acc = 0;
  while (!q.empty()) {
    pair<int, int> edge = q.top();
    int dest = edge.first;
    int cost = edge.second;
    q.pop();
    if (visited[dest]) continue;
    visited[dest] = true;
    acc += cost;
    for (int i = 0; i < (int)edges[dest].size(); i++) {
      q.push(edges[dest][i]);
    }
  }
  return acc;
}
vector<pair<int, int>> A;
int main(void) {
  int N, D;
  cin >> N >> D;
  A.resize(N);
  for (int i = 0; i < N; i++) {
    int a;
    cin >> a;
    A[i].first = i;
    A[i].second = a;
  }
  sort(A.begin(), A.end(),
       [](const pair<int, int> &x, const pair<int, int> &y) {
         return x.second < y.second;
       });
  auto f = [](pair<int, int> x, pair<int, int> y) {
    if (x.second < y.second) {
      return x;
    } else {
      return y;
    }
  };
  pair<int, int> inf = {-1, INF};
  SegmentTree<pair<int, int>, pair<int, int>> *st_left =
      new SegmentTree<pair<int, int>, pair<int, int>>(N, inf, f);
  SegmentTree<pair<int, int>, pair<int, int>> *st_right =
      new SegmentTree<pair<int, int>, pair<int, int>>(N, inf, f);
  edges.resize(N);
  for (int i = 0; i < (int)A.size(); i++) {
    auto p = st_left->query(0, A[i].first);
    if (p != inf) {
      edges[A[i].first].push_back(
          {p.first, p.second + A[i].second - (N - A[i].first) * D});
      edges[p.first].push_back(
          {A[i].first, p.second + A[i].second - (N - A[i].first) * D});
    }
    p = st_right->query(A[i].first + 1, N);
    if (p != inf) {
      edges[A[i].first].push_back(
          {p.first, p.second + A[i].second - A[i].first * D});
      edges[p.first].push_back(
          {A[i].first, p.second + A[i].second - A[i].first * D});
    }
    st_left->update(A[i].first,
                    {A[i].first, A[i].second + (N - A[i].first) * D});
    st_right->update(A[i].first, {A[i].first, A[i].second + A[i].first * D});
  }
  visited.resize(N, false);
  visited[0] = true;
  PriorityQueue q(compare);
  for (int i = 0; i < (int)edges[0].size(); i++) {
    q.push(edges[0][i]);
  }
  cout << solve(q) << endl;
  delete st_left;
  delete st_right;
  return 0;
}
