#include <bits/stdc++.h>
using namespace std;
constexpr double EPS = 1e-9;
constexpr int MAX_ITER = 100;
int w, h, n, d;
vector<double> a, p;
// 주어진 각 구간과 밀도에 대해 총 이동 거리 dx를 반환
// K = p_i * sin(theta_i), target_dx는 이 segment에서 커버할 수평 거리
double compute_dx(double K, const vector<double>& heights, const vector<double>& density) {
double total_x = 0.0;
for (int i = 0; i < (int)heights.size(); ++i) {
double t = K / density[i];
if (t >= 1.0 - EPS) return 1e18;
double cos_theta = sqrt(1.0 - t * t);
total_x += heights[i] * (t / cos_theta);
}
return total_x;
}
double compute_time(double K, const vector<double>& heights, const vector<double>& density) {
double total_time = 0.0;
for (int i = 0; i < (int)heights.size(); ++i) {
double t = K / density[i];
if (t >= 1.0 - EPS) return 1e18;
double cos_theta = sqrt(1.0 - t * t);
total_time += density[i] * (heights[i] / cos_theta);
}
return total_time;
}
double solve_segment(double target_dx, const vector<double>& heights, const vector<double>& density) {
double lo = 0.0, hi = 1e4;
for (int iter = 0; iter < MAX_ITER; ++iter) {
double mid = (lo + hi) / 2.0;
double dx = compute_dx(mid, heights, density);
if (dx < target_dx - EPS)
lo = mid;
else
hi = mid;
}
return compute_time(lo, heights, density);
}
int find_lane(double y) {
if (y < EPS) return 1;
for (int i = 0; i < n; ++i) {
if (y < a[i] - EPS) return i + 1;
}
return n;
}
int main() {
cin >> w >> h;
cin >> n >> d;
a.resize(n);
for (int i = 0; i < n; ++i) cin >> a[i];
p.resize(n);
for (int i = 0; i < n; ++i) cin >> p[i];
int k = find_lane(d);
double min_time = 1e18;
for (int j = k; j <= n; ++j) {
vector<double> up_heights;
double prev = 0.0;
for (int i = 0; i < j - 1; ++i) {
up_heights.push_back(a[i] - prev);
prev = a[i];
}
if (j == 1) up_heights.push_back(d);
else up_heights.push_back(a[j - 1] - prev);
vector<double> up_density(p.begin(), p.begin() + j);
if (j == k) {
double t = solve_segment(w, up_heights, up_density);
min_time = min(min_time, t);
continue;
}
vector<double> down_heights;
prev = a[j - 1];
for (int i = j - 1; i >= k; --i) {
double bottom = (i == 0 ? 0.0 : a[i - 1]);
double hgt = prev - (i == k - 1 ? d : bottom);
down_heights.push_back(hgt);
prev = (i == k - 1 ? d : bottom);
}
vector<double> down_density(p.begin() + k - 1, p.begin() + j);
reverse(down_heights.begin(), down_heights.end());
reverse(down_density.begin(), down_density.end());
// x 를 이분 탐색: up 에서 x 이동, down 에서 w - x 이동
double lo = 0.0, hi = w;
for (int it = 0; it < MAX_ITER; ++it) {
double mid = (lo + hi) / 2.0;
double up_t = solve_segment(mid, up_heights, up_density);
double down_t = solve_segment(w - mid, down_heights, down_density);
double up_t2 = solve_segment(mid + EPS, up_heights, up_density);
double down_t2 = solve_segment(w - mid - EPS, down_heights, down_density);
if (up_t2 + down_t2 < up_t + down_t)
lo = mid;
else
hi = mid;
}
double mid = (lo + hi) / 2.0;
double total = solve_segment(mid, up_heights, up_density) +
solve_segment(w - mid, down_heights, down_density);
min_time = min(min_time, total);
}
cout << fixed << setprecision(10) << min_time << "\n";
return 0;
}