#include <bits/stdc++.h>
using namespace std;
long long N;
long long D;
vector<long long> A;
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  UnionFind() {}
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
UnionFind uf;
set<pair<long long, long long>> S;
map<long long, pair<long long, long long>> mn;
void add(long long x, long long v, long long dsum) {
  auto p = pair<long long, long long>{v - dsum, x};
  int u = uf.root(x);
  if (mn.count(u)) {
    mn[u] = min(mn[u], p);
  } else {
    mn[u] = p;
  }
  S.insert(p);
}
long long INF = 1e18;
pair<long long, long long> find_min(long long x, long long dsum) {
  auto it = S.begin();
  while (it != S.end()) {
    if (mn[uf.root(it->second)] != *it) {
      it = S.erase(it);
      continue;
    }
    if (uf.findSet(x, it->second)) {
      ++it;
    } else {
      break;
    }
  }
  if (it == S.end()) return {INF, INF};
  return {it->first + dsum + A[x], it->second};
}
void init() {
  S.clear();
  mn.clear();
}
bool one_step(long long &ans) {
  init();
  vector<pair<long long, long long>> seq1, seq2;
  for (int i = 0; i < A.size(); i++) {
    auto r = find_min(i, i * D);
    seq1.push_back(r);
    add(i, A[i], i * D);
  }
  init();
  reverse(A.begin(), A.end());
  {
    for (int i = 0; i < A.size(); i++) {
      auto r = find_min(i, i * D);
      seq2.emplace_back(r.first, A.size() - r.second - 1);
      add(i, A[i], i * D);
    }
    reverse(seq2.begin(), seq2.end());
  }
  reverse(A.begin(), A.end());
  bool upd = false;
  map<int, pair<long long, pair<long long, long long>>> minv;
  for (int i = 0; i < seq1.size(); i++) {
    auto p = min(seq1[i], seq2[i]);
    if (minv.count(uf.root(i)) == 0 || minv[uf.root(i)].first > p.first) {
      minv[uf.root(i)] = {p.first, {i, p.second}};
    }
  }
  for (auto &&p : minv) {
    if (p.second.first == INF) continue;
    if (uf.unionSet(p.second.second.first, p.second.second.second)) {
      ans += p.second.first;
      upd = true;
    }
  }
  return upd;
}
void fake_solve() {
  uf = UnionFind(N);
  long long ans = 0;
  while (true) {
    if (!one_step(ans)) break;
  }
  cout << ans << endl;
}
void solve() { fake_solve(); }
void input() {
  N = long long();
  scanf("%lld", &N);
  D = long long();
  scanf("%lld", &D);
  A = vector<long long>(N);
  for (int i = 0; i < N; i++) {
    scanf("%lld", &A[i]);
  }
}
int main() {
  input();
  solve();
  return 0;
}
