#include <bits/stdc++.h>
using namespace std;
const long long LLINF = (1LL << 60);
const long long INF = (1LL << 30);
const double DINF = std::numeric_limits<double>::infinity();
const long long MOD = 1000000007;
class UnionFind {
 public:
  UnionFind(long long size) { m_Data.assign(size, -1); }
  bool Unite(long long x, long long y) {
    x = Find(x), y = Find(y);
    if (x == y) {
      return (false);
    }
    if (m_Data[x] > m_Data[y]) {
      swap(x, y);
    }
    m_Data[x] += m_Data[y];
    m_Data[y] = x;
    return (true);
  }
  long long Find(long long k) {
    if (m_Data[k] < 0) {
      return (k);
    }
    return (m_Data[k] = Find(m_Data[k]));
  }
  long long Size(long long k) { return (-m_Data[Find(k)]); }

 private:
  vector<long long> m_Data;
};
template <typename T>
class Kruskal {
 public:
  struct Edge {
    long long src, to;
    T cost;
    Edge(long long to, T cost) : src(-1), to(to), cost(cost) {}
    Edge(long long src, long long to, T cost) : src(src), to(to), cost(cost) {}
    Edge &operator=(const long long &x) {
      to = x;
      return *this;
    }
    operator long long() const { return to; }
  };

 public:
  Kruskal() {}
  Kruskal(long long v) { Init(v); }
  void Init(long long v) { m_V = v; }
  void AddDEdge(long long from, long long to, T cost) {
    m_Edges.push_back(Edge(from, to, cost));
  }
  void AddUdEdge(long long from, long long to, long long cost) {
    m_Edges.push_back(Edge(from, to, cost));
    m_Edges.push_back(Edge(to, from, cost));
  }
  T GetCost() {
    sort(begin(m_Edges), end(m_Edges),
         [](const Edge &a, const Edge &b) { return (a.cost < b.cost); });
    UnionFind tree(m_V);
    T ret = 0;
    for (auto &e : m_Edges) {
      if (tree.Unite(e.src, e.to)) {
        ret += e.cost;
      }
    }
    return (ret);
  }

 private:
  long long m_V;
  vector<Edge> m_Edges;
};
long long N, D;
vector<long long> A;
Kruskal<long long> kr;
void dfs(long long l, long long r) {
  if (r - l <= 0) {
    return;
  }
  long long mid = (r - l) / 2 + l;
  long long r_min = -1;
  for (long long i = mid + 1; i <= r; ++i) {
    if (r_min < 0 || D * i + A[i] < D * r_min + A[r_min]) {
      r_min = i;
    }
  }
  long long l_min = -1;
  for (long long i = l; i <= mid; ++i) {
    if (l_min < 0 || D * i + A[i] < D * l_min + A[l_min]) {
      l_min = i;
    }
  }
  for (long long i = l; i <= mid; ++i) {
    kr.AddUdEdge(i, r_min, D * abs(i - r_min) + A[i] + A[r_min]);
  }
  for (long long i = mid + 1; i <= r; ++i) {
    kr.AddUdEdge(i, l_min, D * abs(i - l_min) + A[i] + A[l_min]);
  }
  dfs(l, mid);
  dfs(mid + 1, r);
}
long long solve() {
  kr.Init(N);
  dfs(0, N - 1);
  return kr.GetCost();
}
signed main() {
  cin >> N >> D;
  A.resize(N);
  for (long long i = 0; i < N; ++i) {
    cin >> A[i];
  }
  long long ans = solve();
  printf("%lld\n", ans);
  return 0;
}
