#include <bits/stdc++.h>
constexpr int kMaxN = 1e5 + 10;
struct Edge {
  int n1, n2;
  long long cost;
};
int costa[kMaxN];
std::vector<Edge> edges;
Edge NewEdge(int n1, int n2, long long costd) {
  Edge e;
  e.n1 = n1;
  e.n2 = n2;
  e.cost = costd * std::abs(n1 - n2) + costa[n1] + costa[n2];
  return e;
}
void MakeEdge(int low, int upp, long long costd) {
  if (upp - low <= 1) {
    return;
  }
  int mid = (low + upp) / 2;
  MakeEdge(low, mid, costd);
  MakeEdge(mid, upp, costd);
  int min1i = -1;
  long long min1 = 0;
  for (int i = low; i < mid; ++i) {
    long long v = costa[i] - i * (costd);
    if (min1i == -1 || v < min1) {
      min1 = v;
      min1i = i;
    }
  }
  int min2i = -1;
  long long min2 = 0;
  for (int i = mid; i < upp; ++i) {
    long long v = costa[i] + i * (costd);
    if (min2i == -1 || v < min2) {
      min2 = v;
      min2i = i;
    }
  }
  for (int i = low; i < mid; ++i) {
    edges.push_back(NewEdge(i, min2i, costd));
  }
  for (int i = mid; i < upp; ++i) {
    edges.push_back(NewEdge(min1i, i, costd));
  }
}
int union_set_id[kMaxN];
int UnionSetGetRoot(int i) {
  if (i != union_set_id[i]) {
    union_set_id[i] = UnionSetGetRoot(union_set_id[i]);
  }
  return union_set_id[i];
}
void UnionSetUnion(int a, int b) {
  a = UnionSetGetRoot(a);
  b = UnionSetGetRoot(b);
  if (a != b) {
    union_set_id[a] = b;
  }
}
bool CompareEdge(Edge const &e1, Edge const &e2) { return e1.cost < e2.cost; }
int main() {
  int n, d;
  scanf("%d %d", &n, &d);
  for (int i = 0; i < n; ++i) {
    scanf("%d", costa + i);
    union_set_id[i] = i;
  }
  MakeEdge(0, n, d);
  std::sort(edges.begin(), edges.end(), CompareEdge);
  long long total = 0;
  int edge_count = 0;
  for (auto const &edge : edges) {
    if (UnionSetGetRoot(edge.n1) != UnionSetGetRoot(edge.n2)) {
      total += edge.cost;
      UnionSetUnion(edge.n1, edge.n2);
      edge_count += 1;
    }
    if (edge_count == n - 1) {
      break;
    }
  }
  printf("%lld\n", total);
  return 0;
}
