#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int INF = 1e9;
const ll LINF = 1e18;
template<typename T>
void maximize(T& a, const T& b) {
if (a < b) a = b;
}
template<typename T>
void minimize(T& a, const T& b) {
if (b < a) a = b;
}
const int N = 1e5 + 5;
int n, m; ll P, C;
int a[N];
int s[6];
int number_of_subtask() {
if (n <= 10 && m == 1) return 1;
if (m == 2) return 3;
return 4;
}
ll sqr(int x) {
return 1ll * x * x;
}
namespace sub1 {
// Tồn tại một hoán vị sao cho việc chọn các cột gỗ từ 1 đến i (với i nào đấy) để thi công cho ra lợi nhuận tối ưu nhất
void solve() {
sort(a + 1, a + n + 1);
ll best = -LINF;
do {
int mn = INF, mx = -INF;
ll profit = 0;
for (int i = 1; i <= n; i++) {
minimize(mn, a[i]);
maximize(mx, a[i]);
if (i % s[0] == 0) {
profit += P - sqr(mx - mn) * C;
maximize(best, profit);
mn = INF, mx = -INF;
}
}
}
while (next_permutation(a + 1, a + n + 1));
cout << best << '\n';
}
}
// Subtask 3, 4:
// - Với hàm lợi nhuận đã cho (có liên quan đến min, max) thì ý tưởng đầu tiên của ta là sort lại mảng a để thuận tiện cho việc tính toán
// - Sau khi sort, ta cũng rút ra được nhận xét quan trọng như sau:
// Khi thi công 1 ngôi nhà theo mẫu nhà thứ j, để tối ưu nhất thì ta nên chọn s(j) cột gỗ nằm liên tiếp nhau
ll profit(int mn, int mx) {
return P - sqr(mx - mn) * C;
}
namespace sub3 {
ll dp[N][2][2]; // dp[i][0/1][0/1] = Lợi nhuận dự kiến tối đa có thể đạt được khi xét i cột gỗ đầu tiên,
// đã thi công ít nhất 1 ngôi nhà/chưa thi công ngôi nhà nào theo mẫu nhà thứ 1,
// đã thi công ít nhất 1 ngôi nhà/chưa thi công ngôi nhà nào theo mẫu nhà thứ 2
void solve() {
sort(a + 1, a + n + 1);
for (int i = 0; i <= n; i++) {
for (int x = 0; x <= 1; x++) {
for (int y = 0; y <= 1; y++) dp[i][x][y] = -LINF;
}
}
dp[0][0][0] = 0;
for (int i = 0; i < n; i++) {
for (int x = 0; x <= 1; x++) {
for (int y = 0; y <= 1; y++) {
// Bỏ qua cột gỗ thứ i + 1
maximize(dp[i + 1][x][y], dp[i][x][y]);
// Thi công 1 ngôi nhà theo mẫu nhà thứ 1
if (i + s[0] <= n) {
maximize(dp[i + s[0]][1][y], dp[i][x][y] + profit(a[i + 1], a[i + s[0]]));
}
// Thi công 1 ngôi nhà theo mẫu nhà thứ 2
if (i + s[1] <= n) {
maximize(dp[i + s[1]][x][1], dp[i][x][y] + profit(a[i + 1], a[i + s[1]]));
}
}
}
}
cout << dp[n][1][1] << '\n';
}
}
namespace sub4 {
ll dp[N][1 << 6]; // dp[i][mask] = Lợi nhuận dự kiến tối đa có thể đạt được khi xét i cột gỗ đầu tiên
// với mask biểu diễn các mẫu nhà đã có ít nhất 1 ngôi nhà được thi công
// (bit j = 1 <=> mẫu nhà thứ j đã có ít nhất 1 ngôi nhà được thi công)
void solve() {
sort(a + 1, a + n + 1);
for (int i = 0; i <= n; i++) {
for (int mask = 0; mask < (1 << m); mask++) {
dp[i][mask] = -LINF;
}
}
dp[0][0] = 0;
for (int i = 0; i < n; i++) {
for (int mask = 0; mask < (1 << m); mask++) {
// Bỏ qua cột gỗ thứ i + 1
maximize(dp[i + 1][mask], dp[i][mask]);
// Thi công 1 ngôi nhà theo mẫu nhà thứ j nào đấy
for (int j = 0; j < m; j++) {
if (i + s[j] <= n) {
int new_mask = mask | (1 << j);
maximize(dp[i + s[j]][new_mask], dp[i][mask] + profit(a[i + 1], a[i + s[j]]));
}
}
}
}
cout << dp[n][(1 << m) - 1] << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
// freopen("WHOME.INP", "r", stdin);
// freopen("WHOME.OUT", "w", stdout);
cin >> n >> m >> P >> C;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 0; i < m; i++) cin >> s[i];
int subtask = number_of_subtask();
if (subtask == 1) sub1::solve();
if (subtask == 3) sub3::solve();
if (subtask == 4) sub4::solve();
}