/*----------------by syr----------------*/
/*
  -----  -----  -----
  |   |  |---|    _/
  |   |  | \_    /
  -----  |   \  -----

  |---\  \   /  |\  /|
  |   |   \_/   | \/ |
  |   |   / \   |    |
  |---/  /   \  |    |
*/
#include<bits/stdc++.h>

using namespace std;

#define PH push
#define MP make_pair
#define PB push_back
#define fst first
#define snd second
#define FOR(i,x,y) for(int i=(x);i<(y);++i)
#define REP(i,x,y) for(int i=(x);i<=(y);++i)
#define x0 x0123456789
#define y0 y0123456789
#define x1 x1234567890
#define y1 y1234567890
#define x2 x2345678901
#define y2 y2345678901
typedef double db;
typedef long long ll;
typedef long double ldb;
typedef pair<int,int> pii;

const ll INF=1e18+7;
const int maxn=2e5+5;

class SegmentTree{
private:
	int sz;
	struct Node{
		pair<ll,int> v[2];
		Node(){}
		Node(int x):v({MP(INF,x),MP(INF,x)}){}
	}dat[maxn<<2];
	friend Node operator + (Node a,Node b){
		Node ret;
		ret.v[0]=min(a.v[0],b.v[0]);
		ret.v[1]=min(a.v[1],b.v[1]);
		return ret;
	}
	inline void build(int x,int l,int r){
		if(l==r){
			dat[x]=Node(l);
			return;
		}
		int md=(l+r)>>1;
		build(x<<1,l,md);
		build(x<<1|1,md+1,r);
		dat[x]=dat[x<<1]+dat[x<<1|1];
		return;
	}
public:
	inline int size(){return sz;}
	inline void init(int n){
		for(sz=1;sz<n;sz<<=1);
		build(1,0,sz-1);
		return;
	}
	inline void update(int x,int l,int r,int y,ll k,bool f){
		//printf("update: x=%d l=%d r=%d y=%d k=%lld f=%d\n",x,l,r,y,k,f);
		if(l==r){
			dat[x].v[f]=min(dat[x].v[f],MP(k,l));
			return;
		}
		int md=(l+r)>>1;
		if(y<=md) update(x<<1,l,md,y,k,f);
		else update(x<<1|1,md+1,r,y,k,f);
		dat[x]=dat[x<<1]+dat[x<<1|1];
		return;
	}
	inline pair<ll,int> query(int x,int l,int r,int s,int t,bool f){
		//printf("query: x=%d l=%d r=%d s=%d t=%d f=%d\n",x,l,r,s,t,f);
		if(s>t) return MP(INF,-1);
		if(l>=s&&r<=t) return dat[x].v[f];
		int md=(l+r)>>1;
		if(t<=md) return query(x<<1,l,md,s,t,f);
		if(s>md) return query(x<<1|1,md+1,r,s,t,f);
		return min(query(x<<1,l,md,s,t,f),query(x<<1|1,md+1,r,s,t,f));
	}
}seg;

class Dsu{
private:
	int fa[maxn];
public:
	inline void init(int n){FOR(i,0,n) fa[i]=i;return;}
	inline int find(int x){return (x==fa[x])?(x):(fa[x]=find(fa[x]));}
	inline bool combine(int x,int y){
		x=find(x),y=find(y);
		fa[x]=y;
		return (x!=y);
	}
}dsu;

struct Edge{
	ll w;
	int u;
	int v;
	Edge(ll w,int u,int v):w(w),u(u),v(v){}
	inline bool operator < (const Edge &b)const{return w<b.w;}
};

int n;
ll d;
ll ans;
ll a[maxn];
vector<Edge> ed;
vector<pair<ll,int> > vec;

inline ll kruscal(){
	ll ret=0;
	dsu.init(n);
	sort(ed.begin(),ed.end());
	FOR(i,0,ed.size()){
		int u=ed[i].u,v=ed[i].v;
		if(dsu.combine(u,v)) ret+=ed[i].w;
	}
	return ret;
}

int main(){
	scanf("%d%lld",&n,&d);
	FOR(i,0,n) scanf("%d",a+i),vec.PB(MP(a[i],i));
	sort(vec.begin(),vec.end());
	seg.init(n);
	FOR(i,0,vec.size()){
		int u=vec[i].snd;
		pair<ll,int> v0=seg.query(1,0,seg.size()-1,0,u-1,0);
		if(~v0.snd)	ed.PB(Edge(a[u]+u*d+v0.fst,v0.snd,u));
		pair<ll,int> v1=seg.query(1,0,seg.size()-1,u+1,n-1,1);
		if(~v1.snd) ed.PB(Edge(a[u]-u*d+v1.fst,v1.snd,u));
		seg.update(1,0,seg.size()-1,u,a[u]-u*d,0);
		seg.update(1,0,seg.size()-1,u,a[u]+u*d,1);
	}
	ans=kruscal();
	printf("%lld\n",ans);
	return 0;
}


Measured memory_bytes: 41324