module main; // https://kmjp.hatenablog.jp/entry/2015/03/27/0900 より // モンテカルロ法 import std; int N; int[] A, B; int[] getRandArray(double p) { auto v = iota(0, N).array; int[] r; int x; foreach (i; 0 .. N - 1) { double d = uniform(0.0, 1.0); if (d < p) x = 0; else x = (1 + (N - 1 - i) * (d - p) / (1 - p)).to!int; r ~= v[x]; v.remove(x); } r ~= v[0]; return r; } void main() { // 入力 double[2] P; readln.chomp.formattedRead("%d %f %f", N, P[0], P[1]); A = readln.split.to!(int[]); B = readln.split.to!(int[]); // 答えの計算 A.sort; B.sort; // AとBの点数の合計の半分 int T = (A.sum + B.sum) / 2; // 試行回数とAの勝利回数 int total = 0, win = 0; foreach (_; 0 .. 200_000) { total++; auto VA = getRandArray(P[0]); auto VB = getRandArray(P[1]); int x = 0; foreach (y; 0 .. N) if (A[VA[y]] > B[VB[y]]) x += A[VA[y]] + B[VB[y]]; win += x > T; } double ans = win; ans /= total; // 答えの出力 writefln("%.10f", ans); }