#include <bits/stdc++.h>
using namespace std;
struct tree {
  int fa;
  int son[2];
  double L, R, A, B, C, bz, bzA, bzB, bzC;
} tr[700011];
double X[300011], Y[300011], Dz[300011];
double Pz, lim, nc, mc, Min;
int Zer, tot, i, n, root;
long double Ans;
double eps = 1e-10;
void Label(int t, double x, double A, double B, double C) {
  tr[t].L = tr[t].L + x;
  tr[t].R = tr[t].R + x;
  tr[t].C += tr[t].A * x * x / 2.0 - tr[t].B * x;
  tr[t].B -= tr[t].A * x;
  tr[t].bzC += tr[t].bzA * x * x / 2.0 - tr[t].bzB * x;
  tr[t].bzB -= tr[t].bzA * x;
  tr[t].bz += x;
  tr[t].A += A;
  tr[t].B += B;
  tr[t].C += C;
  tr[t].bzA += A;
  tr[t].bzB += B;
  tr[t].bzC += C;
}
void down(int x) {
  if (fabs(tr[x].bz) > eps || fabs(tr[x].bzA) > eps || fabs(tr[x].bzB) > eps ||
      fabs(tr[x].bzC) > eps) {
    if (tr[x].son[0])
      Label(tr[x].son[0], tr[x].bz, tr[x].bzA, tr[x].bzB, tr[x].bzC);
    if (tr[x].son[1])
      Label(tr[x].son[1], tr[x].bz, tr[x].bzA, tr[x].bzB, tr[x].bzC);
    tr[x].bz = 0;
    tr[x].bzA = 0;
    tr[x].bzB = 0;
    tr[x].bzC = 0;
  }
}
void rotate(int x) {
  int z, q, e;
  z = tr[x].fa;
  down(z);
  down(x);
  e = tr[z].son[1] == x;
  tr[z].son[e] = tr[x].son[e ^ 1];
  tr[tr[x].son[e ^ 1]].fa = z;
  tr[x].son[e ^ 1] = z;
  if (tr[z].fa) {
    e = tr[tr[z].fa].son[1] == z;
    tr[tr[z].fa].son[e] = x;
  }
  tr[x].fa = tr[z].fa;
  tr[z].fa = x;
}
void splay(int x) {
  int nt, ft, e1, e2;
  down(x);
  while (tr[x].fa != 0) {
    down(x);
    if (tr[tr[x].fa].fa == 0)
      rotate(x);
    else {
      ft = tr[x].fa;
      nt = tr[ft].fa;
      down(nt);
      down(ft);
      e1 = tr[nt].son[1] == ft;
      e2 = tr[ft].son[1] == x;
      if (e1 == e2) {
        rotate(ft);
        rotate(x);
      } else {
        rotate(x);
        rotate(x);
      }
    }
  }
  down(x);
  root = x;
}
int Find(int x) {
  double Ls, Rs;
  down(x);
  Ls = tr[x].L * tr[x].A + tr[x].B;
  Rs = tr[x].R * tr[x].A + tr[x].B;
  if (Ls > 0) {
    if (tr[x].son[0] != 0)
      return Find(tr[x].son[0]);
    else
      return x;
  } else if (Rs < 0) {
    if (tr[x].son[1] != 0 && tr[x].R <= lim)
      return Find(tr[x].son[1]);
    else
      return x;
  } else
    return x;
}
int findnext(int x) {
  int z = tr[x].son[0];
  if (z == 0)
    return -1;
  else {
    while (tr[z].son[1] != 0) z = tr[z].son[1];
    return z;
  }
}
void Insert(double L, double R, double A, double B, double C) {
  int nxt;
  splay(Zer);
  nxt = findnext(Zer);
  if (nxt != -1) splay(nxt);
  tot++;
  tr[Zer].son[0] = tot;
  tr[tot].fa = Zer;
  tr[tot].L = L;
  tr[tot].R = R;
  tr[tot].A = A;
  tr[tot].B = B;
  tr[tot].C = C;
}
void Add() {
  double yl, yr, ya, yb, yc;
  splay(Zer);
  if (tr[Zer].son[0]) {
    Label(tr[Zer].son[0], nc, 0, 0, 0);
    down(tr[Zer].son[0]);
  }
  if (tr[Zer].son[1]) {
    Label(tr[Zer].son[1], mc, 0, 0, 0);
    down(tr[Zer].son[1]);
  }
  yl = tr[Zer].L;
  yr = tr[Zer].R;
  ya = tr[Zer].A;
  yb = tr[Zer].B;
  yc = tr[Zer].C;
  if (fabs(Pz - yr) > eps) {
    tr[Zer].L = Pz + mc;
    tr[Zer].R = yr + mc;
    tr[Zer].A = ya;
    tr[Zer].B = yb - ya * mc;
    tr[Zer].C = yc + ya * mc * mc / 2.0 - yb * mc;
    if (fabs(Pz - yl) > eps)
      Insert(yl + nc, Pz + nc, ya, yb - ya * nc,
             yc + ya * nc * nc / 2.0 - yb * nc);
    if (fabs(nc - mc) > eps) Insert(Pz + nc, Pz + mc, 0, 0, Min);
  } else {
    if (fabs(nc - mc) > eps) {
      tr[Zer].L = Pz + nc;
      tr[Zer].R = Pz + mc;
      tr[Zer].A = 0;
      tr[Zer].B = 0;
      tr[Zer].C = Min;
      Insert(yl + nc, Pz + nc, ya, yb - ya * nc,
             yc + ya * nc * nc / 2.0 - yb * nc);
    } else {
      tr[Zer].L = yl + nc;
      tr[Zer].R = Pz + nc;
      tr[Zer].A = ya;
      tr[Zer].B = yb - ya * nc;
      tr[Zer].C = yc + ya * nc * nc / 2.0 - yb * nc;
    }
  }
}
int main() {
  scanf("%d%lf%lf%lf", &n, &lim, &nc, &mc);
  for (i = 1; i <= n; i++) scanf("%lf", &X[i]);
  tot++;
  root = tot;
  tr[1].L = 1;
  tr[1].R = lim;
  tr[1].A = 2;
  tr[1].B = -2 * X[1];
  tr[1].C = X[1] * X[1];
  for (i = 2; i <= n; i++) {
    Zer = Find(root);
    Pz = -tr[Zer].B / tr[Zer].A;
    if (Pz < tr[Zer].L) Pz = tr[Zer].L;
    if (Pz > tr[Zer].R) Pz = tr[Zer].R;
    if (Pz > lim) Pz = lim;
    Dz[i - 1] = Pz;
    Min = tr[Zer].A * Pz * Pz / 2.0 + tr[Zer].B * Pz + tr[Zer].C;
    Add();
    splay(Zer);
    Label(Zer, 0, 2, -2.0 * X[i], X[i] * X[i]);
    down(Zer);
  }
  Zer = Find(root);
  Pz = -tr[Zer].B / tr[Zer].A;
  if (Pz < tr[Zer].L) Pz = tr[Zer].L;
  if (Pz > tr[Zer].R) Pz = tr[Zer].R;
  if (Pz > lim) Pz = lim;
  Ans = Pz * Pz * tr[Zer].A / 2.0 + Pz * tr[Zer].B + tr[Zer].C;
  Y[n] = Pz;
  for (i = n - 1; i >= 1; i--) {
    if (Dz[i] + nc <= Y[i + 1] && Y[i + 1] <= Dz[i] + mc)
      Y[i] = Dz[i];
    else if (Y[i + 1] > Dz[i] + mc)
      Y[i] = Y[i + 1] - mc;
    else
      Y[i] = Y[i + 1] - nc;
  }
  for (i = 1; i < n; i++) printf("%.10lf ", Y[i]);
  printf("%.10lf\n", Y[n]);
  Ans = 0;
  for (i = 1; i <= n; i++) Ans += (Y[i] - X[i]) * (Y[i] - X[i]);
  printf("%.10lf\n", (double)Ans);
}
