#include <bits/stdc++.h>
using namespace std;
int Read() {
  char c;
  while (c = getchar(), (c != '-') && (c < '0' || c > '9'))
    ;
  bool neg = (c == '-');
  int ret = (neg ? 0 : c - 48);
  while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + c - 48;
  return neg ? -ret : ret;
}
const int MAXN = 300005;
const long double eps = 1e-10;
struct node {
  long double l, r, a, b, c, dx, da, db, dc;
  int fa, son[2];
  long double F(long double x) { return (a * x + b) * x + c; }
} t[MAXN << 1];
int N, Q, A, B, root, cnt;
long double ans[MAXN], apex[MAXN];
inline int CreateNew(long double l, long double r, long double a = 0,
                     long double b = 0, long double c = 0, int c0 = 0,
                     int c1 = 0) {
  return t[++cnt].l = l, t[cnt].r = r, t[cnt].a = a, t[cnt].b = b, t[cnt].c = c,
         t[cnt].son[0] = c0, t[cnt].son[1] = c1, cnt;
}
inline void MarkX(int x, long double dx) {
  t[x].c += (t[x].a * dx - t[x].b) * dx;
  t[x].dc += (t[x].da * dx - t[x].db) * dx;
  t[x].b += -2 * t[x].a * dx, t[x].db += -2 * t[x].da * dx;
  t[x].l += dx, t[x].r += dx, t[x].dx += dx;
}
inline void MarkY(int x, long double da, long double db, long double dc) {
  t[x].a += da, t[x].b += db, t[x].c += dc;
  t[x].da += da, t[x].db += db, t[x].dc += dc;
}
inline void Pushdown(int x) {
  if (t[x].son[0])
    MarkX(t[x].son[0], t[x].dx), MarkY(t[x].son[0], t[x].da, t[x].db, t[x].dc);
  if (t[x].son[1])
    MarkX(t[x].son[1], t[x].dx), MarkY(t[x].son[1], t[x].da, t[x].db, t[x].dc);
  t[x].dx = t[x].da = t[x].db = t[x].dc = 0;
}
inline void Rotate(int x, int tp) {
  int y = t[x].fa;
  Pushdown(y), Pushdown(x);
  t[y].son[!tp] = t[x].son[tp];
  t[x].fa = t[y].fa;
  if (t[x].son[tp]) t[t[x].son[tp]].fa = y;
  if (t[y].fa)
    t[t[y].fa].son[t[t[y].fa].son[1] == y] = x;
  else
    root = x;
  t[y].fa = x, t[x].son[tp] = y;
}
inline void Splay(int x) {
  for (Pushdown(x); t[x].fa;)
    if (t[x].fa == root)
      Rotate(x, t[t[x].fa].son[0] == x);
    else {
      int y = t[x].fa, z = t[y].fa;
      if (y == t[z].son[0])
        if (x == t[y].son[0])
          Rotate(y, 1), Rotate(x, 1);
        else
          Rotate(x, 0), Rotate(x, 1);
      else if (x == t[y].son[1])
        Rotate(y, 0), Rotate(x, 0);
      else
        Rotate(x, 1), Rotate(x, 0);
    }
}
inline long double FindOpt(int x) {
  for (;;) {
    Pushdown(x);
    long double opt = min(-t[x].b * 0.5 / t[x].a, (long double)Q);
    if (opt < t[x].l - eps)
      if (t[x].son[0])
        x = t[x].son[0];
      else
        return Splay(x), t[x].l;
    else if (opt > t[x].r + eps)
      if (t[x].son[1])
        x = t[x].son[1];
      else
        return Splay(x), t[x].r;
    else
      return Splay(x), opt;
  }
}
int main() {
  scanf("%d%d%d%d", &N, &Q, &A, &B);
  memset(t, 0, sizeof(t));
  root = CreateNew(1, Q);
  for (int i = 1; i <= N; i++) {
    if (i > 1) {
      if (A < B) {
        long double opt = FindOpt(root);
        apex[i] = opt;
        int l(t[root].son[0]), r(t[root].son[1]);
        if (opt - t[root].l > eps) {
          l = CreateNew(t[root].l, opt, t[root].a, t[root].b, t[root].c,
                        t[root].son[0], 0);
          if (t[root].son[0]) t[t[root].son[0]].fa = l;
          t[l].fa = root;
        }
        if (t[root].r - opt > eps) {
          r = CreateNew(opt, t[root].r, t[root].a, t[root].b, t[root].c, 0,
                        t[root].son[1]);
          if (t[root].son[1]) t[t[root].son[1]].fa = r;
          t[r].fa = root;
        }
        if (l) MarkX(l, A);
        if (r) MarkX(r, B);
        t[root].c = t[root].F(opt);
        t[root].son[0] = l, t[root].son[1] = r, t[root].l = opt + A,
        t[root].r = opt + B;
        t[root].a = t[root].b = t[root].da = t[root].db = t[root].dc =
            t[root].dx = 0;
      } else
        MarkX(root, A);
    }
    double x = Read();
    MarkY(root, 1, -2 * x, x * x);
  }
  long double opt = FindOpt(root);
  double sum = t[root].F(opt);
  for (int i = N; i >= 1; i--) {
    ans[i] = opt;
    if (opt > apex[i] + B)
      opt -= B;
    else if (opt < apex[i] + A)
      opt -= A;
    else
      opt = apex[i];
  }
  for (int i = 1; i <= N; i++)
    printf("%.10f%c", (double)ans[i], i < N ? ' ' : '\n');
  printf("%.10f\n", sum);
  return 0;
}
