#include <bits/stdc++.h>
using namespace std;
struct cww {
  cww() {
    if (1) {
      ios::sync_with_stdio(false);
      cin.tie(0);
    }
  }
} star;
template <typename T>
inline bool chmin(T &l, T r) {
  bool a = l > r;
  if (a) l = r;
  return a;
}
template <typename T>
inline bool chmax(T &l, T r) {
  bool a = l < r;
  if (a) l = r;
  return a;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &it : v) is >> it;
  return is;
}
class range {
 private:
  struct I {
    int x;
    int operator*() { return x; }
    bool operator!=(I &lhs) { return x < lhs.x; }
    void operator++() { ++x; }
  };
  I i, n;

 public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  I &begin() { return i; }
  I &end() { return n; }
};
using namespace std;
constexpr int INF = 1e7;
template <typename SEG>
using SetInitialLeaf = function<void(SEG &, int)>;
template <typename SEG>
using SetInitialSegment = function<void(SEG &, const int, const int)>;
template <typename RET, typename SEG>
using GetSingleSegment = function<RET(SEG &, const int, const int)>;
template <typename RET>
using GetMergedSegment = function<RET(RET, RET)>;
template <typename SEG, typename Q>
using UpdateSingleSegment = function<void(SEG &, Q)>;
template <typename SEG>
using LazyUpdate = function<void(SEG &, SEG &, SEG &)>;
int N;
long long D;
long long A[212345];
struct ret {
  int id;
  int bid;
  long long y;
  long long b;
};
struct node {
  ret y;
  long long a;
  bool is_leaf;
};
inline void update(node &v, long long a) {
  chmin(v.a, a);
  if (v.is_leaf || v.y.y > v.a + v.y.b) {
    v.y.y = v.a + v.y.b;
    v.y.id = v.y.bid;
  }
}
SetInitialLeaf<node> set_leaf = [](node &v, const int id) {
  v.y.y = 1e17;
  v.y.id = id;
  v.y.b = A[id % N];
  if (id < N)
    v.y.b += D * (id % N);
  else
    v.y.b += -D * (id % N);
  v.y.bid = id;
  v.a = 1e17;
  update(v, v.a);
};
SetInitialSegment<node> set_segment = [](node &v, const int l, const int r) {
  v.a = 1e17;
  v.is_leaf = (r - l == 1);
};
GetSingleSegment<ret, node> segment_min = [](node &v, const int l,
                                             const int r) { return v.y; };
GetMergedSegment<ret> merge_segment = [](ret l, ret r) {
  ret x;
  if (l.y < r.y) {
    x.id = l.id;
    x.y = l.y;
  } else {
    x.id = r.id;
    x.y = r.y;
  }
  if (l.b < r.b) {
    x.bid = l.bid;
    x.b = l.b;
  } else {
    x.bid = r.bid;
    x.b = r.b;
  }
  return x;
};
UpdateSingleSegment<node, long long> update_b = [](node &v, long long l) {
  v.y.b = l;
  update(v, v.a);
};
UpdateSingleSegment<node, long long> update_a = [](node &v, long long l) {
  update(v, l);
};
LazyUpdate<node> lazy_update = [](node &v, node &l, node &r) {
  update(l, v.a);
  update(r, v.a);
};
template <typename T>
struct BufferManager {
  T *mem;
  int ptr;
  BufferManager(T *mem) {
    ptr = 0;
    this->mem = mem;
  }
  T *get(int m) {
    ptr += m;
    return mem + ptr - m;
  }
  void reset() { ptr = 0; }
};
namespace NodeBuffer {
constexpr int BufferSize = 1612345;
using NodeType = node;
NodeType mem[BufferSize];
BufferManager<NodeType> buffer(mem);
}  // namespace NodeBuffer
template <typename Node, typename RET>
struct SegmentTree {
  int size;
  Node *seg;
  GetSingleSegment<RET, Node> get_single_segment;
  GetMergedSegment<RET> get_merged_segment;
  LazyUpdate<Node> lazy_update;
  void init(int l, int r, SetInitialSegment<Node> &init_segment,
            SetInitialLeaf<Node> &init_leaf, int k = 0) {
    auto &v = seg[k];
    init_segment(v, l, r);
    if (r - l == 1) {
      init_leaf(v, l);
    } else if (r - l > 1) {
      int m = (l + r) / 2;
      init(l, m, init_segment, init_leaf, k * 2 + 1);
      init(m, r, init_segment, init_leaf, k * 2 + 2);
      v.y = get_merged_segment(get_single_segment(seg[k * 2 + 1], l, m),
                               get_single_segment(seg[k * 2 + 2], m, r));
    }
  }
  SegmentTree(
      int n, GetSingleSegment<RET, Node> gss, GetMergedSegment<RET> gms,
      SetInitialSegment<Node> sis, SetInitialLeaf<Node> sil,
      LazyUpdate<Node> lu = [](Node &v, Node &l, Node &r) {},
      BufferManager<Node> &buf = NodeBuffer::buffer)
      : get_single_segment(gss), get_merged_segment(gms), lazy_update(lu) {
    size = 1;
    while (size < n) size *= 2;
    seg = buf.get(size * 2 + 10);
    init(0, size, sis, sil);
  }
  RET get(int a, int b, int k, int l, int r) {
    if (a <= l && r <= b) return get_single_segment(seg[k], l, r);
    if (r - l > 1) lazy_update(seg[k], seg[2 * k + 1], seg[2 * k + 2]);
    int m = (l + r) / 2;
    bool ll = !(m <= a || b <= l);
    bool rr = !(r <= a || b <= m);
    RET ret;
    if (ll && rr)
      ret = get_merged_segment(get(a, b, k * 2 + 1, l, m),
                               get(a, b, k * 2 + 2, m, r));
    else if (ll)
      ret = get(a, b, k * 2 + 1, l, m);
    else
      ret = get(a, b, k * 2 + 2, m, r);
    seg[k].y = get_merged_segment(get_single_segment(seg[k * 2 + 1], l, m),
                                  get_single_segment(seg[k * 2 + 2], m, r));
    return ret;
  }
  RET get(int a, int b) { return get(a, b, 0, 0, size); }
  template <typename Q>
  void update(int a, int b, int k, int l, int r,
              UpdateSingleSegment<Node, Q> &update_segment, Q value) {
    if (r <= a || b <= l) return;
    if (a <= l && r <= b) {
      update_segment(seg[k], value);
    } else {
      if (r - l > 1) lazy_update(seg[k], seg[2 * k + 1], seg[2 * k + 2]);
      int m = (l + r) / 2;
      update(a, b, k * 2 + 1, l, m, update_segment, value);
      update(a, b, k * 2 + 2, m, r, update_segment, value);
      seg[k].y = get_merged_segment(get_single_segment(seg[k * 2 + 1], l, m),
                                    get_single_segment(seg[k * 2 + 2], m, r));
    }
  }
  template <typename Q>
  void update_segment(int a, int b,
                      UpdateSingleSegment<Node, Q> &update_segment, Q value) {
    update(a, b, 0, 0, size, update_segment, value);
  }
  template <typename Q>
  void update_element(int a, UpdateSingleSegment<Node, Q> &update_segment,
                      Q value) {
    update(a, a + 1, 0, 0, size, update_segment, value);
  }
};
int main() {
  cin >> N >> D;
  for (int i : range(N)) {
    cin >> A[i];
  }
  SegmentTree<node, ret> st(2 * N, segment_min, merge_segment, set_segment,
                            set_leaf, lazy_update);
  auto update = [&](int id) {
    st.update_element<long long>(id, update_b, 1e17);
    st.update_element<long long>(id + N, update_b, 1e17);
    if (id > 0)
      st.update_segment<long long>(N, N + id, update_a, A[id] + id * D);
    if (id + 1 < N)
      st.update_segment<long long>(id + 1, N, update_a, A[id] - id * D);
  };
  update(0);
  long long ret = 0;
  for (int i : range(N - 1)) {
    auto ans = st.get(0, 2 * N);
    ret += ans.y;
    update(ans.id % N);
  }
  cout << ret << endl;
  return 0;
}
