#include <bits/stdc++.h>
struct HogeMonoid {
  using Type = int;
  static Type Identity() { return Type(); }
  static Type Operate(const Type& left, const Type& right) { return Type(); }
};
namespace Monoid {
template <class T>
struct Sum {
  using Type = T;
  static Type Identity() { return T(); }
  static Type Operate(const Type& left, const Type& right) {
    return left + right;
  }
};
template <class T>
struct Minimum {
  using Type = T;
  static Type Identity() { return std::numeric_limits<Type>::max(); }
  static Type Operate(const Type& left, const Type& right) {
    return std::min(left, right);
  }
};
template <class T>
struct Maximum {
  using Type = T;
  static Type Identity() { return std::numeric_limits<Type>::min(); }
  static Type Operate(const Type& left, const Type& right) {
    return std::max(left, right);
  }
};
}  // namespace Monoid
template <class Monoid>
class SegmentTree {
  using T = typename Monoid::Type;
  const int level_m;
  const size_t size_m;
  std::vector<T> arr_m;
  static T Identity();
  static T Operate(const T& left, const T& right);
  bool Is_valid_index(size_t pos) const;
  static const int DEFAULT = -1;

 public:
  SegmentTree(int level);
  void Update(size_t pos, const T& value);
  T Query(size_t left, size_t right) const;
  T Get(size_t pos) const;
  void Debug(int level = DEFAULT, int cell_width = 4) const;
};
template <class Monoid>
typename SegmentTree<Monoid>::T SegmentTree<Monoid>::Identity() {
  return Monoid::Identity();
}
template <class Monoid>
typename SegmentTree<Monoid>::T SegmentTree<Monoid>::Operate(const T& left,
                                                             const T& right) {
  return Monoid::Operate(left, right);
}
template <class Monoid>
inline bool SegmentTree<Monoid>::Is_valid_index(size_t pos) const {
  return pos >= 0 && pos < size_m;
}
template <class Monoid>
SegmentTree<Monoid>::SegmentTree(int level)
    : level_m(level), size_m(1 << level) {
  assert(level < 32);
  if (0) {
    assert(0);
  }
  arr_m.resize(size_m * 2, Identity());
}
template <class Monoid>
void SegmentTree<Monoid>::Update(size_t pos, const T& value) {
  pos += size_m;
  arr_m[pos] = value;
  pos >>= 1;
  while (pos > 0) {
    arr_m[pos] = Operate(arr_m[pos * 2], arr_m[pos * 2 + 1]);
    pos >>= 1;
  }
}
template <class Monoid>
typename SegmentTree<Monoid>::T SegmentTree<Monoid>::Query(size_t left,
                                                           size_t right) const {
  assert(left <= right);
  T tmp_left = Identity();
  T tmp_right = Identity();
  left += size_m;
  right += size_m;
  while (left < right) {
    if (left & 1) tmp_left = Operate(tmp_left, arr_m[left++]);
    if (right & 1) tmp_right = Operate(arr_m[--right], tmp_right);
    left >>= 1;
    right >>= 1;
  }
  return Operate(tmp_left, tmp_right);
}
template <class Monoid>
typename SegmentTree<Monoid>::T SegmentTree<Monoid>::Get(size_t pos) const {
  return arr_m[size_m + pos];
}
template <class Monoid>
void SegmentTree<Monoid>::Debug(int level, int cell_width) const {
  auto to_str_fixed = [](const T& value, int max_length) -> std::string {
    std::ostringstream osst;
    osst << value;
    std::string str = osst.str();
    std::string output;
    if (str.size() > max_length) {
      for (int i = 0; i < max_length; ++i) {
        output += '#';
      }
    } else {
      const int remain_length = max_length - str.size();
      const int right_blank = remain_length / 2;
      const int left_blank = remain_length - right_blank;
      for (int i = 0; i < left_blank; ++i) {
        output += ' ';
      }
      output += str;
      for (int i = 0; i < right_blank; ++i) {
        output += ' ';
      }
    }
    return output;
  };
  if (level == DEFAULT) {
    level = level_m;
  }
  if (level > level_m) {
    level = level_m;
  }
  std::vector<std::string> output_strs;
  for (int lev = 0; lev <= level; ++lev) {
    std::string output;
    const int front = size_m >> lev;
    output += '|';
    for (int i = 0; i < (1 << (level - lev)); ++i) {
      output += to_str_fixed(arr_m[front + i], cell_width);
      output += '|';
    }
    output_strs.push_back(output);
    cell_width = cell_width * 2 + 1;
  }
  reverse(output_strs.begin(), output_strs.end());
  for (const std::string& output : output_strs) {
    std::cout << output << std::endl;
  }
}
namespace std {
template <class T, class U>
std::pair<T, U> operator+(std::pair<T, U> left, std::pair<T, U> right) {
  return std::pair<T, U>(left.first + right.first, left.second + right.second);
}
template <class T, class U>
std::pair<T, U> operator-(std::pair<T, U> left, std::pair<T, U> right) {
  return std::pair<T, U>(left.first - right.first, left.second - right.second);
}
};  // namespace std
using namespace std;
const int INF = 0x3FFFFFFF;
const long long INFLL = 0x3FFFFFFF3FFFFFFF;
const double INFD = 1.0e+308;
const string INFSTR = "\x7f";
const double EPS = 1.0e-9;
void YesNo(bool b) { cout << (b ? "Yes" : "No") << endl; }
void YESNO(bool b) { cout << (b ? "YES" : "NO") << endl; }
template <class T, class U>
istream& operator>>(istream& ist, pair<T, U>& right) {
  return ist >> right.first >> right.second;
}
template <class T, class U>
ostream& operator<<(ostream& ost, const pair<T, U>& right) {
  return ost << right.first << ' ' << right.second;
}
template <class T, class TCompatible, size_t N>
void Fill(T (&dest)[N], const TCompatible& val) {
  fill(dest, dest + N, val);
}
template <class T, class TCompatible, size_t M, size_t N>
void Fill(T (&dest)[M][N], const TCompatible& val) {
  for (int i = 0; i < M; ++i) Fill(dest[i], val);
}
template <class T>
T Compare(T left, T right) {
  return left > right ? 1 : (left < right ? -1 : 0);
}
istream& Ignore(istream& ist) {
  string s;
  ist >> s;
  return ist;
}
bool Inside(int i, int j, int h, int w) {
  return i >= 0 && i < h && j >= 0 && j < w;
}
template <class T>
T Next() {
  T buf;
  cin >> buf;
  return buf;
}
istream& operator>>(istream& ist, __int128& val) {
  long long tmp;
  ist >> tmp;
  val = tmp;
  return ist;
}
ostream& operator<<(ostream& ost, __int128 val) {
  long long tmp = val;
  ost << tmp;
  return ost;
}
template <typename T>
using PriorityQ = priority_queue<T, vector<T>, greater<T>>;
struct MinimumPP {
  using Type = pair<long long, long long>;
  static Type Identity() { return pair<long long, long long>(INFLL, INFLL); }
  static Type Operate(const Type& left, const Type& right) {
    return left < right ? left : right;
  }
};
long long N, D;
long long A[200000];
SegmentTree<MinimumPP> Asc(18);
SegmentTree<MinimumPP> Dsc(18);
const long long Huge = INFLL;
int main() {
  cin >> N >> D;
  for (long long i = (0), i_max = (N); i < i_max; ++i) {
    cin >> A[i];
    Asc.Update(i, pair<long long, long long>(A[i] + i * D, i));
    Dsc.Update(i, pair<long long, long long>(A[i] - i * D, i));
  }
  long long sum = 0;
  PriorityQ<pair<long long, pair<long long, long long>>> Q;
  auto mn = Asc.Query(1, N);
  Q.push(make_pair(mn.first + A[0], pair<long long, long long>(0, mn.second)));
  Asc.Update(0, pair<long long, long long>(Huge, 0));
  Dsc.Update(0, pair<long long, long long>(Huge, 0));
  int cnt = 1;
  while (cnt < N) {
    auto p = Q.top();
    Q.pop();
    long long cost = p.first;
    int from = p.second.first;
    int to = p.second.second;
    if (Asc.Get(to).first >= Huge) {
      auto mn =
          Asc.Query(from + 1, N) - pair<long long, long long>(D * from, 0);
      mn =
          min(mn, Dsc.Query(0, from) + pair<long long, long long>(D * from, 0));
      Q.push(make_pair(mn.first + A[from],
                       pair<long long, long long>(from, mn.second)));
      continue;
    }
    Asc.Update(to, pair<long long, long long>(Huge, to));
    Dsc.Update(to, pair<long long, long long>(Huge, to));
    ++cnt;
    sum += cost;
    auto mn2 = Asc.Query(from + 1, N) - pair<long long, long long>(D * from, 0);
    mn2 =
        min(mn2, Dsc.Query(0, from) + pair<long long, long long>(D * from, 0));
    if (mn2.first < Huge)
      Q.push(make_pair(mn2.first + A[from],
                       pair<long long, long long>(from, mn2.second)));
    auto mn = Asc.Query(to + 1, N) - pair<long long, long long>(D * to, 0);
    mn = min(mn, Dsc.Query(0, to) + pair<long long, long long>(D * to, 0));
    Q.push(
        make_pair(mn.first + A[to], pair<long long, long long>(to, mn.second)));
  }
  cout << sum << endl;
  return 0;
}
