package main

import (
  "bufio"
  "fmt"
  "os"
  "sort"
  "strconv"
  "strings"
)

const INF64 int64 = 1000000000000000000
var INF City = City{-1,INF64}

func main() {
  input := Input{bufio.NewReaderSize(os.Stdin,10000)}
  n,d := input.NextInts()
  a := input.NextIntArray()
  lst := NewSegmentTree(n)
  rst := NewSegmentTree(n)
  cs := make(Cities,n)
  for i:=0;i<n;i++ {
    lst.Update(i,City{i,int64(n-i-1)*d+a[i]})
    rst.Update(i,City{i,int64(i)*d+a[i]})
    cs[i] = City{i,a[i]}
  }
  sort.Sort(cs)
  rs := Roads{}
  for _,c := range cs {
    lc := lst.Query(0,c.i)
    if lc != INF {
      rs = append(rs,Road{c.i,lc.i,int64(abs(c.i-lc.i))*d+a[c.i]+a[lc.i]})
    }
    rc := rst.Query(c.i+1,n)
    if rc != INF {
      rs = append(rs,Road{c.i,rc.i,int64(abs(c.i-rc.i))*d+a[c.i]+a[rc.i]})
    }
    lst.Update(c.i,INF)
    rst.Update(c.i,INF)
  }
  sort.Sort(rs)
  u := NewUnionFind(n)
  ans := int64(0)
  for i:=0;i<len(rs);i++ {
    if u.Same(rs[i].x,rs[i].y) { continue }
    ans += rs[i].cost
    u.Unite(rs[i].x,rs[i].y)
  }
  fmt.Println(ans)
}
func abs(n int) int {
  if n < 0 { return -n }
  return n
}

type City struct { i int;cost int64 }
type Cities []City
func(c Cities) Len() int { return len(c) }
func(c Cities) Swap(i,j int) { c[i],c[j] = c[j],c[i] }
func(c Cities) Less(i,j int) bool { return c[i].cost > c[j].cost }

type Road struct { x,y int;cost int64 }
type Roads []Road
func(r Roads) Len() int { return len(r) }
func(r Roads) Swap(i,j int) { r[i],r[j] = r[j],r[i] }
func(r Roads) Less(i,j int) bool { return r[i].cost < r[j].cost }

type SegmentTree struct { n,p int;c Cities }
func NewSegmentTree(n int) SegmentTree {
  p := 1
  for p < n { p *= 2 }
  c := make(Cities,2*p-1)
  for i:=0;i<2*p-1;i++ { c[i] = INF }
  return SegmentTree{n,p,c}
}
func op(a,b City) City {
  if a.cost < b.cost { return a }
  return b
}
func(st SegmentTree) Update(i int,c City) {
  i += st.p-1
  st.c[i] = c
  for i > 0 {
    i = (i-1)/2
    st.c[i] = op(st.c[2*i+1],st.c[2*i+2])
  }
}
func(st SegmentTree) Query(l,r int) City {
  l += st.p-1
  r += st.p-1
  ret := INF
  for l < r {
    if l%2 == 0 { ret = op(ret,st.c[l]) }
    if r%2 == 0 { ret = op(ret,st.c[r-1]) }
    l = l/2
    r = (r-1)/2
  }
  return ret
}

type UnionFind struct { par,rank []int }
func NewUnionFind(n int) UnionFind {
  par := make([]int,n)
  rank := make([]int,n)
  for i:=0;i<n;i++ { par[i] = i }
  return UnionFind{par,rank}
}
func(u UnionFind) Find(i int) int {
  if u.par[i] == i { return i }
  u.par[i] = u.Find(u.par[i])
  return u.par[i]
}
func(u UnionFind) Same(i,j int) bool { return u.Find(i) == u.Find(j) }
func(u UnionFind) Unite(i,j int) {
  i,j = u.Find(i),u.Find(j)
  if i == j { return }
  if u.rank[i] < u.rank[j] { u.par[i] = j;return }
  u.par[j] = i
  if u.rank[i] == u.rank[j] { u.rank[i]++ }
}

type Input struct { reader *bufio.Reader }
func(i *Input) NextLine() string {
  var buffer []byte
  for {
    line,isPrefix,err := i.reader.ReadLine()
    if err != nil { panic(err) }
    buffer = append(buffer,line...)
    if !isPrefix { break }
  }
  return string(buffer)
}
func(i *Input) NextInts() (int,int64) {
  s := strings.Fields(i.NextLine())
  x,_ := strconv.Atoi(s[0])
  y,_ := strconv.ParseInt(s[1],10,64)
  return x,y
}
func(i *Input) NextIntArray() []int64 {
  s := strings.Fields(i.NextLine())
  a := make([]int64,len(s))
  for i:=0;i<len(s);i++ { a[i],_ = strconv.ParseInt(s[i],10,64) }
  return a
}

Measured memory_bytes: 64384