Problem:
E: 鬼畜ババ抜き - Unbalanced Old Maid -
物語
高坂さんと園田さんと南さんは子供の頃からの仲良し3人組だ。3人は沖縄に修学旅行に行くも、台風が来てしまい、海で遊ぶことができないのでババ抜きをすることにした。
園田さんは勝負事には強いが、ポーカーフェイスが苦手なため、自分のカードが引かれるときに無意識にかわいらしい顔芸を披露してしまう。園田さんを愛して止まない高坂さんと南さんは、園田さんの顔芸を見るだけで園田さんの手札が分かってしまうため、園田さんのカードを引くときは、自分が有利になるように引くことができる。
一方、高坂さんと南さんは特に顔芸をしたりはしないので、手札がばれることはない。 よって、高坂さんと南さんのカードを引く人はそれぞれ、高坂さんと南さんが持っているカードの中から等確率で1枚引く。
どう考えても不利な園田さんは、ババ抜きでなかなか勝てないことに違和感を覚えている。 使用するカードの種類数
n
と初期の手札が与えられたとき、園田さんが負けとならない確率を求めてあげよう。
問題文
高坂さん、園田さん、南さんの3人は、以下の状況でババ抜きを行う。
使用するカードは、1から
n
までの整数が書かれた
n
種類のカードそれぞれ4枚ずつとジョーカー1枚の合計
4n+1
枚である。
最初の手札が与えられたとき、3人はそれぞれ自分の手札に同一の整数が書かれたカードのペア（2枚組）があるならば、そのようなペアを全て捨てる。
3人は「高坂さんが南さんの手札からカードを引く」、「園田さんが高坂さんの手札からカードを引く」「南さんが園田さんの手札からカードを引く」という順番（ターン）で以下の操作を繰り返す。（このババ抜きでは、カードを引いた人が、次に引かれるというルールであることに注意せよ。）
一人がジョーカーのみを持ち、その人以外の2人の手札が空のとき、ババ抜きは終了し、ジョーカーを持っている人が負けとなる。
カードを引く順番の人の手札が空のとき、ターンを次の人とし、1.に戻る。
そうでなければ、カードを引く順番の人は決められた相手からカードを1枚引く。ただし、相手の手札が空のとき、まだ残っているもう1人からカードを引く。
引いたカードと同じ整数が書かれたカードがカードを引いた人の手札にあれば、その2枚を捨てる。
ターンを次の人とし、1.へ戻る。
ただし、園田さんのカードを引く人（南さんか高坂さん）は、以下の戦略でカード引く。
もし自分のカードと園田さんのカードで同じ整数が書かれたカードがあれば、それらのうち最小の整数が書かれたカードを引く
そうでないとき、園田さんがジョーカーでないカードを持っていれば、それらのうち最小の整数が書かれたカードを引く
そうでないなら、園田さんはジョーカーしか持っていないので、ジョーカーを引く
高坂さんと南さんのカードを引く人は、それぞれ高坂さんと南さんが持っているカードの中から等確率で1枚引く。
使用するカードの種類数
n
と3人の初期の手札が与えられたとき、園田さんが負けとならない確率を求めてあげよう。
入力形式
入力は4行からなり、以下の形式で与えられる。
n
m_1
c_{1,1}
...
c_{1,m_1}
m_2
c_{2,1}
...
c_{2,m_2}
m_3
c_{3,1}
...
c_{3,m_3}
1行目にジョーカー以外のカードの種類数
n
が与えられる。 
続く入力は3行からなり、2行目に高坂さんの手札、3行目に園田さんの手札、4行目に南さんの手札の情報が与えられる。
i+1 (1 ≤ i ≤ 3)
行目では行頭に手持ちの枚数
m_i
、続けて手持ちのカードを表す
m_i
個の整数
c_{i,j} (1 ≤ j ≤ m_i)
が空白区切りで与えられる。
0
はジョーカー、
1
から
n
はカードに書かれた整数を表す。
制約
1 ≤ n ≤ 100
m_1+m_2+m_3 = 4n+1
3人の手札で0はちょうど1つ、
1
から
n
はちょうど4回ずつ現れる
0 ≤ c_{i,j} ≤ n
(
1 ≤ i ≤ 3
,
1 ≤ j ≤ m_i
)
出力形式
園田さんが負けとならない確率を1行に出力せよ。答えには
10^{−6}
を超える絶対誤差があってはならない。
入力例1
1
1 1
3 0 1 1
1 1
出力例1
0.0
高坂さんが南さんのカード1を引き、高坂さんと南さんは手札が空になる。
園田さんはどうしても勝つことはできない。
入力例2
1
2 1 1
1 1
2 0 1
出力例2
0.5
はじめの高坂さんのターンは、高坂さんの手札が既に空なので何もしない。次の園田さんのターンでは、園田さんは南さんの手札のうちそれぞれ0.5の確率でカード1かジョーカーを引く。カード1を引いたとき、園田さんの手札は空となり勝利する。一方ジョーカーを引いたときは、次の南さんのターンで、南さんは確実にカード1を引くので園田さんが負けとなる。
入力例3
2
3 0 1 2
3 1 2 2
3 1 1 2
出力例3
0.5
入力例4
2
2 0 1
6 2 2 2 1 1 1
1 2
出力例4
0.6666666667

Submitted solutions:

code_snippet: #include <iostream>
#include <tuple>
#include <vector>
using namespace std;

int N;
int M[3], P[3][409];
int Cnt[3][109];
double prevs[109][109][109][3];
double dp[109][109][109][3];
double Answer = 0.0;

int main() {
	// Step 1. Input
	cin >> N;
	cin >> M[0]; for (int i = 0; i < M[0]; i++) cin >> P[0][i];
	cin >> M[1]; for (int i = 0; i < M[1]; i++) cin >> P[1][i];
	cin >> M[2]; for (int i = 0; i < M[2]; i++) cin >> P[2][i];

	// Step 2. Precount
	for (int i = 0; i < M[0]; i++) Cnt[0][P[0][i]] += 1;
	for (int i = 0; i < M[1]; i++) Cnt[1][P[1][i]] += 1;
	for (int i = 0; i < M[2]; i++) Cnt[2][P[2][i]] += 1;
	for (int i = 0; i < 3; i++) {
		for (int j = 1; j <= N; j++) Cnt[i][j] %= 2;
	}
	int ab_ = 0, bc_ = 0, ca_ = 0, j_ = -1;
	for (int i = 1; i <= N; i++) {
		if (Cnt[0][i] == 1 && Cnt[1][i] == 1) ab_ += 1;
		if (Cnt[1][i] == 1 && Cnt[2][i] == 1) bc_ += 1;
		if (Cnt[2][i] == 1 && Cnt[0][i] == 1) ca_ += 1;
	}
	if (Cnt[0][0] == 1) j_ = 0;
	if (Cnt[1][0] == 1) j_ = 1;
	if (Cnt[2][0] == 1) j_ = 2;
	prevs[ab_][bc_][ca_][j_] = 1.0;
	if (ab_ + bc_ + ca_ == 0 && j_ != 1) Answer += 1.0;

	// Step 3. Dynamic Programming
	for (int i = 0; i <= (ab_ + bc_ + ca_) * 8 + 100; i++) {
		int lims = ((ab_ + bc_ + ca_) * 8 + 100 - i) / 8;
		lims = min(lims, ab_ + bc_ + ca_);

		// Start
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims - ab; bc++) {
				for (int ca = 0; ca <= lims - ab - bc; ca++) {
					for (int j = 0; j <= 2; j++) {
						if (prevs[ab][bc][ca][j] == 0) continue;
						if (ab + bc + ca == 0) continue;
						int nex = (j + 2) % 3;
						int numa = ab + ca + (j == 0 ? 1 : 0);
						int numb = bc + ab + (j == 1 ? 1 : 0);
						int numc = ca + bc + (j == 2 ? 1 : 0);

						// Case 1
						if (numa == 0) {
							dp[bc][ca][ab][nex] += prevs[ab][bc][ca][j];
						}

						// Case 2
						else if (numc != 0 && i % 3 != 2) {
							int joker_flag = (j == 2 ? 1 : 0);
							dp[bc][ca][ab][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numc);
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j] * (1.0 * ca / numc);
							if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j] * (1.0 * bc / numc);
						}

						// Case 3
						else if (numc != 0 && i % 3 == 2) {
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j];
							else if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j];
							else dp[bc][ca][ab][2] += prevs[ab][bc][ca][j];
						}

						// Case 4
						else if (numb != 0 && i % 3 != 0) {
							int joker_flag = (j == 1 ? 1 : 0);
							dp[bc][ca][ab - 0][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numb);
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j] * (1.0 * ab / numb);
						}

						// Case 5
						else if (numb != 0 && i % 3 == 0) {
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j];
						}
					}
				}
			}
		}

		// Refresh
		// printf("%d: %.12lf\n", i, Answer);
		if (i % 3 != 0) Answer += dp[0][0][0][0];
		if (i % 3 != 1) Answer += dp[0][0][0][2];
		if (i % 3 != 2) Answer += dp[0][0][0][1];
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims; bc++) {
				for (int ca = 0; ca <= lims; ca++) {
					for (int j = 0; j <= 2; j++) {
						prevs[ab][bc][ca][j] = dp[ab][bc][ca][j];
						dp[ab][bc][ca][j] = 0;
					}
				}
			}
		}
	}

	// Step 4. Output
	printf("%.12lf\n", Answer);
	return 0;
}
accuracy: 1
time_ms: 590
memory_kb: 54204
final_rank: 5

code_snippet: #include <iostream>
#include <tuple>
#include <vector>
using namespace std;

int N;
int M[3], P[3][409];
int Cnt[3][109];
double prevs[109][109][109][3];
double dp[109][109][109][3];
double Answer = 0.0;

int main() {
	// Step 1. Input
	cin >> N;
	cin >> M[0]; for (int i = 0; i < M[0]; i++) cin >> P[0][i];
	cin >> M[1]; for (int i = 0; i < M[1]; i++) cin >> P[1][i];
	cin >> M[2]; for (int i = 0; i < M[2]; i++) cin >> P[2][i];

	// Step 2. Precount
	for (int i = 0; i < M[0]; i++) Cnt[0][P[0][i]] += 1;
	for (int i = 0; i < M[1]; i++) Cnt[1][P[1][i]] += 1;
	for (int i = 0; i < M[2]; i++) Cnt[2][P[2][i]] += 1;
	for (int i = 0; i < 3; i++) {
		for (int j = 1; j <= N; j++) Cnt[i][j] %= 2;
	}
	int ab_ = 0, bc_ = 0, ca_ = 0, j_ = -1;
	for (int i = 1; i <= N; i++) {
		if (Cnt[0][i] == 1 && Cnt[1][i] == 1) ab_ += 1;
		if (Cnt[1][i] == 1 && Cnt[2][i] == 1) bc_ += 1;
		if (Cnt[2][i] == 1 && Cnt[0][i] == 1) ca_ += 1;
	}
	if (Cnt[0][0] == 1) j_ = 0;
	if (Cnt[1][0] == 1) j_ = 1;
	if (Cnt[2][0] == 1) j_ = 2;
	prevs[ab_][bc_][ca_][j_] = 1.0;
	if (ab_ + bc_ + ca_ == 0 && j_ != 1) Answer += 1.0;

	// Step 3. Dynamic Programming
	for (int i = 0; i <= (ab_ + bc_ + ca_) * 8 + 100; i++) {
		int lims = ((ab_ + bc_ + ca_) * 8 + 100 - i) / 8;
		lims = min(lims, ab_ + bc_ + ca_);

		// Start
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims - ab; bc++) {
				for (int ca = 0; ca <= lims - ab - bc; ca++) {
					for (int j = 0; j <= 2; j++) {
						if (prevs[ab][bc][ca][j] == 0) continue;
						if (ab + bc + ca == 0) continue;
						int nex = (j + 2) % 3;

						// Case 1
						if (ab + ca == 0) {
							dp[bc][ca][ab][nex] += prevs[ab][bc][ca][j];
						}

						// Case 2
						else if (bc + ca + (j == 2 ? 1 : 0) != 0 && i % 3 != 2) {
							int joker_flag = (j == 2 ? 1 : 0);
							int numc = bc + ca + joker_flag;
							dp[bc][ca][ab][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numc);
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j] * (1.0 * ca / numc);
							if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j] * (1.0 * bc / numc);
						}

						// Case 3
						else if (bc + ca + (j == 2 ? 1 : 0) != 0 && i % 3 == 2) {
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j];
							else if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j];
							else dp[bc][ca][ab][2] += prevs[ab][bc][ca][j];
						}

						// Case 4
						else if (i % 3 != 0) {
							int joker_flag = (j == 1 ? 1 : 0);
							int numb = ab + joker_flag;
							dp[bc][ca][ab - 0][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numb);
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j] * (1.0 * ab / numb);
						}

						// Case 5
						else if (i % 3 == 0) {
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j];
						}
					}
				}
			}
		}

		// Refresh
		// printf("%d: %.12lf\n", i, Answer);
		if (i % 3 != 0) Answer += dp[0][0][0][0];
		if (i % 3 != 1) Answer += dp[0][0][0][2];
		if (i % 3 != 2) Answer += dp[0][0][0][1];
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims; bc++) {
				for (int ca = 0; ca <= lims; ca++) {
					for (int j = 0; j <= 2; j++) {
						prevs[ab][bc][ca][j] = dp[ab][bc][ca][j];
						dp[ab][bc][ca][j] = 0;
					}
				}
			}
		}
	}

	// Step 4. Output
	printf("%.12lf\n", Answer);
	return 0;
}
accuracy: 0.11904761904761904
time_ms: 360
memory_kb: 45836
final_rank: 6

code_snippet: #include <iostream>
#include <tuple>
#include <vector>
using namespace std;

int N;
int M[3], P[3][409];
int Cnt[3][109];
double prevs[109][109][109][3];
double dp[109][109][109][3];
double Answer = 0.0;

int main() {
	// Step 1. Input
	cin >> N;
	cin >> M[0]; for (int i = 0; i < M[0]; i++) cin >> P[0][i];
	cin >> M[1]; for (int i = 0; i < M[1]; i++) cin >> P[1][i];
	cin >> M[2]; for (int i = 0; i < M[2]; i++) cin >> P[2][i];

	// Step 2. Precount
	for (int i = 0; i < M[0]; i++) Cnt[0][P[0][i]] += 1;
	for (int i = 0; i < M[1]; i++) Cnt[1][P[1][i]] += 1;
	for (int i = 0; i < M[2]; i++) Cnt[2][P[2][i]] += 1;
	for (int i = 0; i < 3; i++) {
		for (int j = 1; j <= N; j++) Cnt[i][j] %= 2;
	}
	int ab_ = 0, bc_ = 0, ca_ = 0, j_ = -1;
	for (int i = 1; i <= N; i++) {
		if (Cnt[0][i] == 1 && Cnt[1][i] == 1) ab_ += 1;
		if (Cnt[1][i] == 1 && Cnt[2][i] == 1) bc_ += 1;
		if (Cnt[2][i] == 1 && Cnt[0][i] == 1) ca_ += 1;
	}
	if (Cnt[0][0] == 1) j_ = 0;
	if (Cnt[1][0] == 1) j_ = 1;
	if (Cnt[2][0] == 1) j_ = 2;
	prevs[ab_][bc_][ca_][j_] = 1.0;
	if (ab_ + bc_ + ca_ == 0 && j_ != 1) Answer += 1.0;

	// Step 3. Dynamic Programming
	for (int i = 0; i <= (ab_ + bc_ + ca_) * 8 + 100; i++) {
		int lims = ((ab_ + bc_ + ca_) * 8 + 100 - i) / 8;
		lims = min(lims, ab_ + bc_ + ca_);

		// Start
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims - ab; bc++) {
				for (int ca = 0; ca <= lims - ab - bc; ca++) {
					for (int j = 0; j <= 2; j++) {
						if (prevs[ab][bc][ca][j] == 0) continue;
						if (ab + bc + ca == 0) continue;
						int nex = (j + 2) % 3;

						// Case 1
						if (ab + ca == 0) {
							dp[bc][ca][ab][nex] += prevs[ab][bc][ca][j];
						}

						// Case 2
						else if (bc + ca != 0 && i % 3 != 2) {
							int joker_flag = (j == 2 ? 1 : 0);
							int numc = bc + ca + joker_flag;
							dp[bc][ca][ab][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numc);
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j] * (1.0 * ca / numc);
							if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j] * (1.0 * bc / numc);
						}

						// Case 3
						else if (bc + ca != 0 && i % 3 == 2) {
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j];
							else if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j];
							else dp[bc][ca][ab][2] += prevs[ab][bc][ca][j];
						}

						// Case 4
						else if (bc + ca == 0 && i % 3 != 0) {
							int joker_flag = (j == 1 ? 1 : 0);
							int numb = ab + joker_flag;
							dp[bc][ca][ab - 0][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numb);
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j] * (1.0 * ab / numb);
						}

						// Case 5
						else if (bc + ca == 0 && i % 3 == 0) {
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j];
						}
					}
				}
			}
		}

		// Refresh
		// printf("%d: %.12lf\n", i, Answer);
		if (i % 3 != 0) Answer += dp[0][0][0][0];
		if (i % 3 != 1) Answer += dp[0][0][0][2];
		if (i % 3 != 2) Answer += dp[0][0][0][1];
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims; bc++) {
				for (int ca = 0; ca <= lims; ca++) {
					for (int j = 0; j <= 2; j++) {
						prevs[ab][bc][ca][j] = dp[ab][bc][ca][j];
						dp[ab][bc][ca][j] = 0;
					}
				}
			}
		}
	}

	// Step 4. Output
	printf("%.12lf\n", Answer);
	return 0;
}
accuracy: 0.09523809523809523
time_ms: 360
memory_kb: 45660
final_rank: 12

code_snippet: #include <iostream>
#include <tuple>
#include <vector>
using namespace std;

int N;
int M[3], P[3][409];
int Cnt[3][109];
double prevs[109][109][109][3];
double dp[109][109][109][3];
double Answer = 0.0;

int main() {
	// Step 1. Input
	cin >> N;
	cin >> M[0]; for (int i = 0; i < M[0]; i++) cin >> P[0][i];
	cin >> M[1]; for (int i = 0; i < M[1]; i++) cin >> P[1][i];
	cin >> M[2]; for (int i = 0; i < M[2]; i++) cin >> P[2][i];

	// Step 2. Precount
	for (int i = 0; i < M[0]; i++) Cnt[0][P[0][i]] += 1;
	for (int i = 0; i < M[1]; i++) Cnt[1][P[1][i]] += 1;
	for (int i = 0; i < M[2]; i++) Cnt[2][P[2][i]] += 1;
	for (int i = 0; i < 3; i++) {
		for (int j = 1; j <= N; j++) Cnt[i][j] %= 2;
	}
	int ab_ = 0, bc_ = 0, ca_ = 0, j_ = -1;
	for (int i = 1; i <= N; i++) {
		if (Cnt[0][i] == 1 && Cnt[1][i] == 1) ab_ += 1;
		if (Cnt[1][i] == 1 && Cnt[2][i] == 1) bc_ += 1;
		if (Cnt[2][i] == 1 && Cnt[0][i] == 1) ca_ += 1;
	}
	if (Cnt[0][0] == 1) j_ = 0;
	if (Cnt[1][0] == 1) j_ = 1;
	if (Cnt[2][0] == 1) j_ = 2;
	prevs[ab_][bc_][ca_][j_] = 1.0;
	if (ab_ + bc_ + ca_ == 0 && j_ != 1) Answer += 1.0;

	// Step 3. Dynamic Programming
	for (int i = 0; i <= (ab_ + bc_ + ca_) * 8 + 100; i++) {
		int lims = ((ab_ + bc_ + ca_) * 8 + 100 - i) / 8;
		lims = min(lims, ab_ + bc_ + ca_);

		// Start
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims - ab; bc++) {
				for (int ca = 0; ca <= lims - ab - bc; ca++) {
					for (int j = 0; j <= 2; j++) {
						if (prevs[ab][bc][ca][j] == 0) continue;
						if (ab + bc + ca == 0) continue;
						int nex = (j + 2) % 3;

						// Case 1
						if (ab + ca == 0) {
							dp[bc][ca][ab][nex] += prevs[ab][bc][ca][j];
						}

						// Case 2
						else if (bc + ca != 0 && i % 3 != 2) {
							int joker_flag = (j == 2 ? 1 : 0);
							int numc = bc + ca + joker_flag;
							dp[bc][ca][ab][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numc);
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j] * (1.0 * ca / numc);
							if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j] * (1.0 * bc / numc);
						}

						// Case 3
						else if (bc + ca != 0 && i % 3 == 2) {
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j];
							else if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j];
							else dp[bc][ca][ab][2] += prevs[ab][bc][ca][j];
						}

						// Case 4
						if (bc + ca == 0 && i % 3 != 0) {
							int joker_flag = (j == 1 ? 1 : 0);
							int numb = ab + joker_flag;
							dp[bc][ca][ab - 0][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numb);
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j] * (1.0 * ab / numb);
						}

						// Case 5
						if (bc + ca == 0 && i % 3 == 0) {
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j];
						}
					}
				}
			}
		}

		// Refresh
		// printf("%d: %.12lf\n", i, Answer);
		if (i % 3 != 0) Answer += dp[0][0][0][0];
		if (i % 3 != 1) Answer += dp[0][0][0][2];
		if (i % 3 != 2) Answer += dp[0][0][0][1];
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims; bc++) {
				for (int ca = 0; ca <= lims; ca++) {
					for (int j = 0; j <= 2; j++) {
						prevs[ab][bc][ca][j] = dp[ab][bc][ca][j];
						dp[ab][bc][ca][j] = 0;
					}
				}
			}
		}
	}

	// Step 4. Output
	printf("%.12lf\n", Answer);
	return 0;
}
accuracy: 0.09523809523809523
time_ms: 360
memory_kb: 45836
final_rank: 13

code_snippet: #include <iostream>
#include <tuple>
#include <vector>
using namespace std;

int N;
int M[3], P[3][409];
int Cnt[3][109];
double prevs[109][109][109][3];
double dp[109][109][109][3];
double Answer = 0.0;

int main() {
	// Step 1. Input
	cin >> N;
	cin >> M[0]; for (int i = 0; i < M[0]; i++) cin >> P[0][i];
	cin >> M[1]; for (int i = 0; i < M[1]; i++) cin >> P[1][i];
	cin >> M[2]; for (int i = 0; i < M[2]; i++) cin >> P[2][i];

	// Step 2. Precount
	for (int i = 0; i < M[0]; i++) Cnt[0][P[0][i]] += 1;
	for (int i = 0; i < M[1]; i++) Cnt[1][P[1][i]] += 1;
	for (int i = 0; i < M[2]; i++) Cnt[2][P[2][i]] += 1;
	for (int i = 0; i < 3; i++) {
		for (int j = 1; j <= N; j++) Cnt[i][j] %= 2;
	}
	int ab_ = 0, bc_ = 0, ca_ = 0, j_ = -1;
	for (int i = 1; i <= N; i++) {
		if (Cnt[0][i] == 1 && Cnt[1][i] == 1) ab_ += 1;
		if (Cnt[1][i] == 1 && Cnt[2][i] == 1) bc_ += 1;
		if (Cnt[2][i] == 1 && Cnt[0][i] == 1) ca_ += 1;
	}
	if (Cnt[0][0] == 1) j_ = 0;
	if (Cnt[1][0] == 1) j_ = 1;
	if (Cnt[2][0] == 1) j_ = 2;
	prevs[ab_][bc_][ca_][j_] = 1.0;

	// Step 3. Dynamic Programming
	for (int i = 0; i <= (ab_ + bc_ + ca_) * 8 + 100; i++) {
		int lims = ((ab_ + bc_ + ca_) * 8 + 100 - i) / 8;
		lims = min(lims, ab_ + bc_ + ca_);

		// Start
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims - ab; bc++) {
				for (int ca = 0; ca <= lims - ab - bc; ca++) {
					for (int j = 0; j <= 2; j++) {
						if (prevs[ab][bc][ca][j] == 0) continue;
						if (ab + bc + ca == 0) continue;
						int nex = (j + 2) % 3;

						// Case 1
						if (ab + ca == 0) {
							dp[bc][ca][ab][nex] += prevs[ab][bc][ca][j];
						}

						// Case 2
						else if (bc + ca != 0 && i % 3 != 2) {
							int joker_flag = (j == 2 ? 1 : 0);
							int numc = bc + ca + joker_flag;
							dp[bc][ca][ab][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numc);
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j] * (1.0 * ca / numc);
							if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j] * (1.0 * bc / numc);
						}

						// Case 3
						else if (bc + ca != 0 && i % 3 == 2) {
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j];
							else if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j];
							else dp[bc][ca][ab][2] += prevs[ab][bc][ca][j];
						}

						// Case 4
						if (bc + ca == 0 && i % 3 != 0) {
							int joker_flag = (j == 1 ? 1 : 0);
							int numb = ab + joker_flag;
							dp[bc][ca][ab - 0][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numb);
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j] * (1.0 * ab / numb);
						}

						// Case 5
						if (bc + ca == 0 && i % 3 == 0) {
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j];
						}
					}
				}
			}
		}

		// Refresh
		// printf("%d: %.12lf\n", i, Answer);
		if (i % 3 != 0) Answer += dp[0][0][0][0];
		if (i % 3 != 1) Answer += dp[0][0][0][2];
		if (i % 3 != 2) Answer += dp[0][0][0][1];
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims; bc++) {
				for (int ca = 0; ca <= lims; ca++) {
					for (int j = 0; j <= 2; j++) {
						prevs[ab][bc][ca][j] = dp[ab][bc][ca][j];
						dp[ab][bc][ca][j] = 0;
					}
				}
			}
		}
	}

	// Step 4. Output
	printf("%.12lf\n", Answer);
	return 0;
}
accuracy: 0.09523809523809523
time_ms: 360
memory_kb: 45876
final_rank: 14

code_snippet: #include <iostream>
#include <tuple>
#include <vector>
using namespace std;

int N;
int M[3], P[3][409];
int Cnt[3][109];
double prevs[109][109][109][3];
double dp[109][109][109][3];
double Answer = 0.0;

int main() {
	// Step 1. Input
	cin >> N;
	cin >> M[0]; for (int i = 0; i < M[0]; i++) cin >> P[0][i];
	cin >> M[1]; for (int i = 0; i < M[1]; i++) cin >> P[1][i];
	cin >> M[2]; for (int i = 0; i < M[2]; i++) cin >> P[2][i];

	// Step 2. Precount
	for (int i = 0; i < M[0]; i++) Cnt[0][P[0][i]] += 1;
	for (int i = 0; i < M[1]; i++) Cnt[1][P[1][i]] += 1;
	for (int i = 0; i < M[2]; i++) Cnt[2][P[2][i]] += 1;
	for (int i = 0; i < 3; i++) {
		for (int j = 1; j <= N; j++) Cnt[i][j] %= 2;
	}
	int ab_ = 0, bc_ = 0, ca_ = 0, j_ = -1;
	for (int i = 1; i <= N; i++) {
		if (Cnt[0][i] == 1 && Cnt[1][i] == 1) ab_ += 1;
		if (Cnt[1][i] == 1 && Cnt[2][i] == 1) bc_ += 1;
		if (Cnt[2][i] == 1 && Cnt[0][i] == 1) ca_ += 1;
	}
	if (Cnt[0][0] == 1) j_ = 0;
	if (Cnt[1][0] == 1) j_ = 1;
	if (Cnt[2][0] == 1) j_ = 2;
	prevs[ab_][bc_][ca_][j_] = 1.0;

	// Step 3. Dynamic Programming
	for (int i = 0; i <= (ab_ + bc_ + ca_) * 5 + 10; i++) {
		int lims = ((ab_ + bc_ + ca_) * 5 + 10 - i) / 5;
		lims = min(lims, ab_ + bc_ + ca_);

		// Start
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims - ab; bc++) {
				for (int ca = 0; ca <= lims - ab - bc; ca++) {
					for (int j = 0; j <= 2; j++) {
						if (prevs[ab][bc][ca][j] == 0) continue;
						if (ab + bc + ca == 0) continue;
						int nex = (j + 2) % 3;

						// Case 1
						if (ab + ca == 0) {
							dp[bc][ca][ab][nex] += prevs[ab][bc][ca][j];
						}

						// Case 2
						else if (bc + ca != 0 && i % 3 != 2) {
							int joker_flag = (j == 2 ? 1 : 0);
							int numc = bc + ca + joker_flag;
							dp[bc][ca][ab][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numc);
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j] * (1.0 * ca / numc);
							if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j] * (1.0 * bc / numc);
						}

						// Case 3
						else if (bc + ca != 0 && i % 3 == 2) {
							if (ca >= 1) dp[bc - 0][ca - 1][ab - 0][nex] += prevs[ab][bc][ca][j];
							else if (bc >= 1) dp[bc - 1][ca - 0][ab + 1][nex] += prevs[ab][bc][ca][j];
							else dp[bc][ca][ab][2] += prevs[ab][bc][ca][j];
						}

						// Case 4
						if (bc + ca == 0 && i % 3 != 0) {
							int joker_flag = (j == 1 ? 1 : 0);
							int numb = ab + joker_flag;
							dp[bc][ca][ab - 0][2] += prevs[ab][bc][ca][j] * (1.0 * joker_flag / numb);
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j] * (1.0 * ab / numb);
						}

						// Case 5
						if (bc + ca == 0 && i % 3 == 0) {
							dp[bc][ca][ab - 1][nex] += prevs[ab][bc][ca][j];
						}
					}
				}
			}
		}

		// Refresh
		if (i % 3 != 0) Answer += dp[0][0][0][0];
		if (i % 3 != 1) Answer += dp[0][0][0][2];
		if (i % 3 != 2) Answer += dp[0][0][0][1];
		for (int ab = 0; ab <= lims; ab++) {
			for (int bc = 0; bc <= lims; bc++) {
				for (int ca = 0; ca <= lims; ca++) {
					for (int j = 0; j <= 2; j++) {
						prevs[ab][bc][ca][j] = dp[ab][bc][ca][j];
						dp[ab][bc][ca][j] = 0;
					}
				}
			}
		}
	}

	// Step 4. Output
	printf("%.12lf\n", Answer);
	return 0;
}
accuracy: 0.09523809523809523
time_ms: 140
memory_kb: 45928
final_rank: 11

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum Type{
	A,
	C,
	B,
};

int N,POW[4];
int table[105],COUNT[3][105];
double dp[101][101][101][3][3];
Type type_array[3] = {A,C,B};


double recursive(int ab,int ac,int bc,Type joker,Type turn){

	if(dp[ab][ac][bc][joker][turn] >= 0){

		return dp[ab][ac][bc][joker][turn];
	}

	int num_A = ab+ac;
	int num_B = ab+bc;
	int num_C = ac+bc;

	switch(joker){
	case A:
		num_A++;
		break;
	case B:
		num_B++;
		break;
	case C:
		num_C++;
		break;
	}

	if(turn == A && num_A == 0){

		return dp[ab][ac][bc][joker][turn] = recursive(ab,ac,bc,joker,C);

	}else if(turn == C && num_C == 0){

		return dp[ab][ac][bc][joker][turn] = 1.0;

	}else if(turn == B && num_B == 0){

		return dp[ab][ac][bc][joker][turn] = recursive(ab,ac,bc,joker,A);
	}

	if(num_A+num_B+num_C == 1){

		if(num_C == 1){

			return dp[ab][ac][bc][joker][turn] = 0;
		}else{

			return dp[ab][ac][bc][joker][turn] = 1.0;
		}
	}

	double ret = 0;

	if(turn == A){

		if(num_B == 0){

			if(num_C == 1){ //C,非負け

				return dp[ab][ac][bc][joker][turn] = 1.0;

			}else{ //2枚以上あるなら、非jokerは少なくとも1枚ある

				if(ac > 0){

					return dp[ab][ac][bc][joker][turn] = recursive(ab,ac-1,bc,joker,C);

				}else{ //bc > 0

					//bが0枚なのであり得ない
				}
			}

		}else{ //num_B > 0

			if(ab > 0){

				ret += recursive(ab-1,ac,bc,joker,C)*((double)ab/(double)num_B);
			}
			if(bc > 0){

				ret += recursive(ab,ac+1,bc-1,joker,C)*((double)bc/(double)num_B);
			}
			if(joker == B){

				ret += recursive(ab,ac,bc,A,C)*(1.0/(double)num_B);
			}
		}

	}else if(turn == B){

		if(num_C == 0){//C:非負け

			return dp[ab][ac][bc][joker][turn] = 1.0;

		}else{ //num_C > 0

			if(num_C == 1){ //C,非負け

				return dp[ab][ac][bc][joker][turn] = 1.0;

			}else{ //2枚以上あるなら、非jokerは少なくとも1枚ある

				if(bc > 0){

					return dp[ab][ac][bc][joker][turn] = recursive(ab,ac,bc-1,joker,A);

				}else{ //ac > 0

					return dp[ab][ac][bc][joker][turn] = recursive(ab+1,ac-1,bc,joker,A);
				}
			}
		}

	}else{ //turn == C

		if(num_A == 0){ //Bから引く

			if(ab > 0){

				//Aが0なのであり得ない
			}
			if(bc > 0){

				ret += recursive(ab,ac,bc-1,joker,B)*((double)bc/(double)num_B);
			}
			if(joker == B){

				ret += recursive(ab,ac,bc,C,B)*(1.0/(double)num_B);
			}

		}else{ //num_A > 0

			if(ab > 0){

				ret += recursive(ab-1,ac,bc+1,joker,B)*((double)ab/(double)num_A);
			}
			if(ac > 0){

				ret += recursive(ab,ac-1,bc,joker,B)*((double)ac/(double)num_A);
			}
			if(joker == A){

				ret += recursive(ab,ac,bc,C,B)*(1.0/(double)num_A);
			}
		}
	}

	return dp[ab][ac][bc][joker][turn] = ret;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i < 4; i++){

		POW[i] = POW[i-1]*2;
	}

	scanf("%d",&N);

	for(int i = 1; i <= N; i++){
		for(int k = 0; k < 3; k++){
			COUNT[k][i] = 0;
		}
	}

	int num,tmp;
	Type joker = A;

	for(int i = 0; i < 3; i++){
		scanf("%d",&num);
		for(int k = 0; k < num; k++){
			scanf("%d",&tmp);

			COUNT[i][tmp]++;

			if(tmp == 0){

				joker = type_array[i];
			}
		}
	}

	for(int i = 0; i < 3; i++){
		for(int k = 1; k <= N; k++){
			if(COUNT[i][k]%2 == 1){

				table[k] += POW[i];
			}
		}
	}



	int ab = 0,ac = 0,bc = 0;
	for(int i = 1; i <= N; i++){
		if(table[i] == 0)continue;

		switch(table[i]){
		case 3:
			ac++;
			break;
		case 5:
			ab++;
			break;
		case 6:
			bc++;
			break;
		}
	}

	for(int i = 0; i <= N; i++){
		for(int k = 0; k <= N; k++){
			for(int p = 0; p <= N; p++){
				for(int a = 0; a < 3; a++){
					for(int b = 0; b < 3; b++){

						dp[i][k][p][a][b] = -1;
					}
				}
			}
		}
	}

	printf("%.10lf\n",recursive(ab,ac,bc,joker,A));

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 75660
final_rank: 1

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum Type{
	A,
	C,
	B,
};

int N,POW[4];
int table[105],COUNT[3][105];
double dp[101][101][101][3][3];
Type type_array[3] = {A,C,B};


double recursive(int ab,int ac,int bc,Type joker,Type turn){

	if(dp[ab][ac][bc][joker][turn] >= 0){

		return dp[ab][ac][bc][joker][turn];
	}

	int num_A = ab+ac;
	int num_B = ab+bc;
	int num_C = ac+bc;

	switch(joker){
	case A:
		num_A++;
		break;
	case B:
		num_B++;
		break;
	case C:
		num_C++;
		break;
	}

	if(turn == A && num_A == 0){

		return dp[ab][ac][bc][joker][turn] = recursive(ab,ac,bc,joker,C);

	}else if(turn == C && num_C == 0){

		return dp[ab][ac][bc][joker][turn] = 1.0;

	}else if(turn == B && num_B == 0){

		return dp[ab][ac][bc][joker][turn] = recursive(ab,ac,bc,joker,A);
	}

	if(num_A+num_B+num_C == 1){

		if(num_C == 1){

			return dp[ab][ac][bc][joker][turn] = 0;
		}else{

			return dp[ab][ac][bc][joker][turn] = 1.0;
		}
	}

	double ret = 0;

	if(turn == A){

		if(num_B == 0){

			if(num_C == 1){ //C,非負け

				return dp[ab][ac][bc][joker][turn] = 1.0;

			}else{ //2枚以上あるなら、非jokerは少なくとも1枚ある

				if(ac > 0){

					return dp[ab][ac][bc][joker][turn] = recursive(ab,ac-1,bc,joker,C);

				}else{ //bc > 0

					//bが0枚なのであり得ない
				}
			}

		}else{ //num_B > 0

			if(ab > 0){

				ret += recursive(ab-1,ac,bc,joker,C)*((double)ab/(double)num_B);
			}
			if(bc > 0){

				ret += recursive(ab,ac+1,bc-1,joker,C)*((double)bc/(double)num_B);
			}
			if(joker == B){

				ret += recursive(ab,ac,bc,A,C)*(1.0/(double)num_B);
			}
		}

	}else if(turn == B){

		if(num_C == 0){//C:非負け

			return dp[ab][ac][bc][joker][turn] = 1.0;

		}else{ //num_C > 0

			if(num_C == 1){ //C,非負け

				return dp[ab][ac][bc][joker][turn] = 1.0;

			}else{ //2枚以上あるなら、非jokerは少なくとも1枚ある

				if(bc > 0){

					return dp[ab][ac][bc][joker][turn] = recursive(ab,ac,bc-1,joker,A);

				}else{ //ac > 0

					return dp[ab][ac][bc][joker][turn] = recursive(ab+1,ac-1,bc,joker,A);
				}
			}
		}

	}else{ //turn == C

		if(num_A == 0){ //Bから引く

			if(ab > 0){

				//Aが0なのであり得ない
			}
			if(bc > 0){

				ret += recursive(ab,ac,bc-1,joker,B)*((double)bc/(double)num_B);
			}
			if(joker == B){

				ret += recursive(ab,ac,bc,C,B)*(1.0/(double)num_B);
			}

		}else{ //num_A > 0

			if(ab > 0){

				ret += recursive(ab-1,ac,bc+1,joker,B)*((double)ab/(double)num_A);
			}
			if(ac > 0){

				ret += recursive(ab,ac-1,bc,joker,B)*((double)ac/(double)num_A);
			}
			if(joker == A){

				ret += recursive(ab,ac,bc,C,B)*(1.0/(double)num_A);
			}
		}
	}

	return dp[ab][ac][bc][joker][turn] = ret;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i < 4; i++){

		POW[i] = POW[i-1]*2;
	}

	scanf("%d",&N);

	for(int i = 1; i <= N; i++){
		for(int k = 0; k < 3; k++){
			COUNT[k][i] = 0;
		}
	}

	int num,tmp;
	Type joker = A;

	for(int i = 0; i < 3; i++){
		scanf("%d",&num);
		for(int k = 0; k < num; k++){
			scanf("%d",&tmp);

			COUNT[i][tmp]++;

			if(tmp == 0){

				//printf("joker:%d\n",i);
				joker = type_array[i];
			}
		}
	}

	for(int i = 0; i < 3; i++){
		for(int k = 1; k <= N; k++){
			if(COUNT[i][k]%2 == 1){

				table[k] += POW[i];
			}
		}
	}



	int ab = 0,ac = 0,bc = 0;
	for(int i = 1; i <= N; i++){
		if(table[i] == 0)continue;

		switch(table[i]){
		case 3:
			ac++;
			break;
		case 5:
			ab++;
			break;
		case 6:
			bc++;
			break;
		}
	}

	for(int i = 0; i <= N; i++){
		for(int k = 0; k <= N; k++){
			for(int p = 0; p <= N; p++){
				for(int a = 0; a < 3; a++){
					for(int b = 0; b < 3; b++){

						dp[i][k][p][a][b] = -1;
					}
				}
			}
		}
	}

	//printf("ab:%d ac:%d bc:%d\n",ab,ac,bc);

	printf("%.10lf\n",recursive(ab,ac,bc,joker,A));

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 75688
final_rank: 2

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "functional"

using namespace std;

int N, M, K, L, R, H, W;
//long long int N,M,K,L,R,H,W;

constexpr long long int MOD = 1000000007;
//constexpr  int MOD=1000000007;
//constexpr int MOD=998244353;
//constexpr long long int MOD=998244353;

constexpr long double EPS = 1e-8;

long double dp[101][101][101][3][3];

double Search(int ab, int bc, int ca, int j, int t) {
	//cout<<ab<<" "<<bc<<" "<<ca<<" "<<j<<" "<<t<<endl;
	if (dp[ab][bc][ca][j][t] >= 0)return dp[ab][bc][ca][j][t];
	if (!ab && !bc && !ca) {
		if (j == 1)return dp[0][0][0][1][t] = 0;
		else return dp[0][0][0][j][t] = 1;
	}
	if (!ab && !bc&&j != 1 && t == 1)return dp[ab][bc][ca][j][t] = Search(ab, bc, ca, j, 2);
	if (!bc && !ca&&j != 2 && t == 2)return dp[ab][bc][ca][j][t] = Search(ab, bc, ca, j, 0);
	if (!ca && !ab&&j != 0 && t == 0)return dp[ab][bc][ca][j][t] = Search(ab, bc, ca, j, 1);
	//nxが1のとき不正が発生
	int nx;
	if (t == 0) {
		nx = 2;
		if (!bc && !ca&&j != 2) {
			nx = 1;
			if (!ab) {
				if (j == 0)return dp[ab][bc][ca][j][t] = 1;
				else return dp[ab][bc][ca][j][t] = 0;
			}
		}
	}
	else if (t == 1) {
		nx = 0;
		if (!ab && !ca&&j != 0) {
			nx = 2;
			if (!bc) {
				if (j == 1)return dp[ab][bc][ca][j][t] = 0;
				else return dp[ab][bc][ca][j][t] = 1;
			}
		}
	}
	else {
		nx = 1;
		if (!ab && !bc&&j != 1) {
			nx = 0;
			if (!ca) {
				return dp[ab][bc][ca][j][t] = 0;
			}
		}
	}
	if (nx == 1) {
		if (t == 0) {
			return dp[ab][bc][ca][j][t] = Search(ab - 1, bc, ca, j, 1);
		}
		if (t == 2) {
			if (bc) {
				if (ab || ca || j == 0)return dp[ab][bc][ca][j][t] = Search(ab, bc - 1, ca, j, 0);
				else return dp[ab][bc][ca][j][t] = Search(ab, bc - 1, ca, j, 1);
			}
			else {
				if (ab) {
					if (ab - 1 || bc || j == 1)return dp[ab][bc][ca][j][t] = Search(ab - 1, bc, ca, j, 1);
					else if (bc || ca || j == 2)return dp[ab][bc][ca][j][t] = Search(ab - 1, bc, ca, j, 2);
					else return dp[ab][bc][ca][j][t] = 1;
				}
				else {
					return dp[ab][bc][ca][j][t] = Search(ab, bc, ca - 1, 2, t);
				}
			}
		}
	}
	if (nx == 2) {
		if (t == 1) {
			if (j == 1) {
				return dp[ab][bc][ca][j][t] = Search(ab, bc - 1, ca, j, 2);
			}
			else {
				return dp[ab][bc][ca][j][t] = Search(ab, bc - 1, ca, j, 2)*bc / (bc + 1) + Search(ab, bc - 1, ca, 1, 1) / (bc + 1);
			}
		}
		if (t == 0) {
			if (ca) {
				if (ab || bc || j == 1)return dp[ab][bc][ca][j][t] = Search(ab, bc, ca - 1, j, 1);
				else return dp[ab][bc][ca][j][t] = Search(ab, bc, ca - 1, j, 2);
			}
			else {
				if (bc)return dp[ab][bc][ca][j][t] = Search(ab + 1, bc - 1, ca, j, 1);
				else dp[ab][bc][ca][j][t] = Search(ab, bc, ca, 0, 1);
				//if(bc){
				//	if(j==2)return dp[ab][bc][ca][j][t]=Search(ab,bc-1,ca,j,2);
				//	else dp[ab][bc][ca][j][t]=Search(ab,bc-1,ca,j,0);
				//}
				//else{
				//	dp[ab][bc][ca][j][t]=Search(ab-1,bc,ca,j,0);
				//}
			}
		}
	}
	if (nx == 0) {
		if (t == 2) {
			return dp[ab][bc][ca][j][t] = Search(ab, bc, ca - 1, j, 0);
		}
		if (t == 1) {
			if (bc || ca || j == 2) {
				if (j != 0) {
					return dp[ab][bc][ca][j][t] = Search(ab - 1, bc, ca, j, 2)*ab / (ab + ca) + Search(ab, bc, ca - 1, j, 0)*ca / (ab + ca);
				}
				else {
					if (bc)return dp[ab][bc][ca][j][t] = Search(ab - 1, bc, ca, j, 2)*ab / (ab + ca + 1) + Search(ab, bc, ca - 1, j, 0)*ca / (ab + ca + 1) + Search(ab, bc - 1, ca, 1, 0) / (ab + ca + 1);
					else return dp[ab][bc][ca][j][t] = Search(ab - 1, bc, ca, j, 2)*ab / (ab + ca + 1) + Search(ab, bc, ca - 1, j, 0)*ca / (ab + ca + 1) + Search(ab - 1, bc, ca, 1, 1) / (ab + ca + 1);
				}
			}
			else {
				if (j == 1) {
					return dp[ab][bc][ca][j][t] = Search(ab - 1, bc, ca, j, 0);
				}
				else {
					return dp[ab][bc][ca][j][t] = Search(ab - 1, bc, ca, j, 0)*ab / (ab + 1);
				}
			}
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> N;
	vector<int>a(101);
	vector<int>b(101);
	vector<int>c(101);
	cin >> M;
	for (int i = 0; i<M; i++) {
		cin >> K;
		a[K] ^= 1;
	}
	cin >> M;
	for (int i = 0; i<M; i++) {
		cin >> K;
		b[K] ^= 1;
	}
	cin >> M;
	for (int i = 0; i<M; i++) {
		cin >> K;
		c[K] ^= 1;
	}
	int ab = 0, bc = 0, ca = 0;
	for (int i = 1; i <= N; i++)ab += a[i] & b[i];
	for (int i = 1; i <= N; i++)bc += b[i] & c[i];
	for (int i = 1; i <= N; i++)ca += c[i] & a[i];
	int joker = 0;
	if (b[0])joker = 1;
	if (c[0])joker = 2;
	int turn = 0;
	for (int i = 0; i <= 100; i++)for (int j = 0; j <= 100; j++)for (int k = 0; k <= 100; k++)for (int l = 0; l<3; l++)for (int m = 0; m<3; m++)dp[i][j][k][l][m] = -1;
	cout << setprecision(20) << Search(ab, bc, ca, joker, turn) << endl;
	//for(int i=0;i<=N;i++)for(int j=0;j<=N;j++)for(int k=0;k<=N;k++)for(int l=0;l<3;l++)for(int m=0;m<3;m++)if(dp[i][j][k][l][m]>=0)cout<<i<<" "<<j<<" "<<k<<" "<<l<<" "<<m<<" "<<dp[i][j][k][l][m]<<endl;
	return 0;
}
accuracy: 0.09523809523809523
time_ms: 40
memory_kb: 148176
final_rank: 15

code_snippet: #include "bits/stdc++.h"

using namespace std;

int N,M,K,L,R,H,W;
//long long int N,M,K,L,R,H,W;

constexpr long long int MOD=1000000007;
//constexpr  int MOD=1000000007;
//constexpr int MOD=998244353;
//constexpr long long int MOD=998244353;

constexpr long double EPS=1e-8;

long double dp[101][101][101][3][3];

double Search(int ab,int bc,int ca,int j,int t){
	//cout<<ab<<" "<<bc<<" "<<ca<<" "<<j<<" "<<t<<endl;
	if(dp[ab][bc][ca][j][t]>=0)return dp[ab][bc][ca][j][t];
	if(!ab&&!bc&&!ca){
		if(j==1)return dp[0][0][0][1][t]=0;
		else return dp[0][0][0][j][t]=1;
	}
	if(!ab&&!bc&&j!=1&&t==1)return dp[ab][bc][ca][j][t]=Search(ab,bc,ca,j,2);
	if(!bc&&!ca&&j!=2&&t==2)return dp[ab][bc][ca][j][t]=Search(ab,bc,ca,j,0);
	if(!ca&&!ab&&j!=0&&t==0)return dp[ab][bc][ca][j][t]=Search(ab,bc,ca,j,1);
	//nxが1のとき不正が発生
	int nx;
	if(t==0){
		nx=2;
		if(!bc&&!ca&&j!=2){
			nx=1;
			if(!ab){
				if(j==0)return dp[ab][bc][ca][j][t]=1;
				else return dp[ab][bc][ca][j][t]=0;
			}
		}
	}
	else if(t==1){
		nx=0;
		if(!ab&&!ca&&j!=0){
			nx=2;
			if(!bc){
				if(j==1)return dp[ab][bc][ca][j][t]=0;
				else return dp[ab][bc][ca][j][t]=1;
			}
		}
	}
	else {
		nx=1;
		if(!ab&&!bc&&j!=1){
			nx=0;
			if(!ca){
				return dp[ab][bc][ca][j][t]=0;
			}
		}
	}
	if(nx==1){
		if(t==0){
			return dp[ab][bc][ca][j][t]=Search(ab-1,bc,ca,j,1);
		}
		if(t==2){
			if(bc){
				if(ab||ca||j==0)return dp[ab][bc][ca][j][t]=Search(ab,bc-1,ca,j,0);
				else return dp[ab][bc][ca][j][t]=Search(ab,bc-1,ca,j,1);
			}
			else{
				if(ab){
					if(ab-1||bc||j==1)return dp[ab][bc][ca][j][t]=Search(ab-1,bc,ca,j,1);
					else if(bc||ca||j==2)return dp[ab][bc][ca][j][t]=Search(ab-1,bc,ca,j,2);
					else return dp[ab][bc][ca][j][t]=1;
				}
				else{
					return dp[ab][bc][ca][j][t]=Search(ab,bc,ca-1,2,t);
				}
			}
		}
	}
	if(nx==2){
		if(t==1){
			if(j==1){
				return dp[ab][bc][ca][j][t]=Search(ab,bc-1,ca,j,2);
			}
			else {
				return dp[ab][bc][ca][j][t]=Search(ab,bc-1,ca,j,2)*bc/(bc+1)+Search(ab,bc-1,ca,1,1)/(bc+1);
			}
		}
		if(t==0){
			if(ca){
				if(ab||bc||j==1)return dp[ab][bc][ca][j][t]=Search(ab,bc,ca-1,j,1);
				else return dp[ab][bc][ca][j][t]=Search(ab,bc,ca-1,j,2);
			}
			else{
				if(bc)return dp[ab][bc][ca][j][t]=Search(ab+1,bc-1,ca,j,1);
				else dp[ab][bc][ca][j][t]=Search(ab,bc,ca,0,1);
				//if(bc){
				//	if(j==2)return dp[ab][bc][ca][j][t]=Search(ab,bc-1,ca,j,2);
				//	else dp[ab][bc][ca][j][t]=Search(ab,bc-1,ca,j,0);
				//}
				//else{
				//	dp[ab][bc][ca][j][t]=Search(ab-1,bc,ca,j,0);
				//}
			}
		}
	}
	if(nx==0){
		if(t==2){
			return dp[ab][bc][ca][j][t]=Search(ab,bc,ca-1,j,0);
		}
		if(t==1){
			if(bc||ca||j==2){
				if(j!=0){
					return dp[ab][bc][ca][j][t]=Search(ab-1,bc,ca,j,2)*ab/(ab+ca)+Search(ab,bc,ca-1,j,0)*ca/(ab+ca);
				}
				else{
					if(bc)return dp[ab][bc][ca][j][t]=Search(ab-1,bc,ca,j,2)*ab/(ab+ca+1)+Search(ab,bc,ca-1,j,0)*ca/(ab+ca+1)+Search(ab,bc-1,ca,1,0)/(ab+ca+1);
					else return dp[ab][bc][ca][j][t]=Search(ab-1,bc,ca,j,2)*ab/(ab+ca+1)+Search(ab,bc,ca-1,j,0)*ca/(ab+ca+1)+Search(ab-1,bc,ca,1,1)/(ab+ca+1);
				}
			}
			else{
				if(j==1){
					return dp[ab][bc][ca][j][t]=Search(ab-1,bc,ca,j,0);
				}
				else{
					return dp[ab][bc][ca][j][t]=Search(ab-1,bc,ca,j,0)*ab/(ab+1);
				}
			}
		}
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	cin>>N;
	vector<int>a(101);
	vector<int>b(101);
	vector<int>c(101);
	cin>>M;
	for(int i=0;i<M;i++){
		cin>>K;
		a[K]^=1;
	}
	cin>>M;
	for(int i=0;i<M;i++){
		cin>>K;
		b[K]^=1;
	}
	cin>>M;
	for(int i=0;i<M;i++){
		cin>>K;
		c[K]^=1;
	}
	int ab=0,bc=0,ca=0;
	for(int i=1;i<=N;i++)ab+=a[i]&b[i];
	for(int i=1;i<=N;i++)bc+=b[i]&c[i];
	for(int i=1;i<=N;i++)ca+=c[i]&a[i];
	int joker=0;
	if(b[0])joker=1;
	if(c[0])joker=2;
	int turn =0;
	for(int i=0;i<=100;i++)for(int j=0;j<=100;j++)for(int k=0;k<=100;k++)for(int l=0;l<3;l++)for(int m=0;m<3;m++)dp[i][j][k][l][m]=-1;
	cout<<setprecision(20)<<Search(ab,bc,ca,joker,turn)<<endl;
	//for(int i=0;i<=N;i++)for(int j=0;j<=N;j++)for(int k=0;k<=N;k++)for(int l=0;l<3;l++)for(int m=0;m<3;m++)if(dp[i][j][k][l][m]>=0)cout<<i<<" "<<j<<" "<<k<<" "<<l<<" "<<m<<" "<<dp[i][j][k][l][m]<<endl;
	return 0;
}
accuracy: 0.09523809523809523
time_ms: 40
memory_kb: 148184
final_rank: 16

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld =long double;
const ld eps = 1e-9;


//namespace cent {
//
//	struct Edge {
//		int src;
//		int dst;
//		long long int cost;
//	};
//	using Graph = vector<vector<Edge>>;
//
//	class Centroid {
//	private:
//		int dfs(const Graph&g, const int now, const int from, vector<int>&ch_nums, const vector<int>&oks) {
//			int sum = 1;
//			for (auto &&e : g[now]) {
//				if (e.dst == from || oks[e.dst] != -1)continue;
//				else {
//					sum += dfs(g, e.dst, e.src, ch_nums, oks);
//				}
//			}
//			return ch_nums[now] = sum;
//		}
//
//		int find_centroid(const int asize, const vector<vector<Edge>>&graph, const int pre_root, const int pre_from, const vector<int>&ch_nums, const vector<int>&oks) {
//			for (auto&& e : graph[pre_root]) {
//				if (e.dst == pre_from)continue;
//				if (oks[e.dst] != -1)continue;
//				if (ch_nums[e.dst]>asize / 2)return find_centroid(asize, graph, e.dst, e.src, ch_nums, oks);
//			}
//			return pre_root;
//		}
//
//		void dfs2(const Graph&g, const int root,const int now, const int from, const vector<int>&oks,int depth) {
//			mp[make_pair(root,now)]=depth;
//			for (auto &&e : g[now]) {
//				if (e.dst == from || oks[e.dst] != -1)continue;
//				else {
//					dfs2(g,root,e.dst,e.src,oks,depth+1);
//				}
//			}
//		};
//
//
//		void cent(const vector<vector<Edge>>&graph, vector<int>&oks, const int root, const int from, vector<vector<int>>&centroid_edges, int& fst_centroid, int depth, vector<int>&ch_nums) {
//			dfs(graph, root, from, ch_nums, oks);
//
//			int cent_id = find_centroid(ch_nums[root], graph, root, from, ch_nums, oks);
//
//
//			dfs2(graph,cent_id,cent_id,-1,oks,0);
//			lens1[cent_id][make_pair(0,0)]--;
//			lens2[cent_id][0]--;
//
//
//			oks[cent_id] = depth;
//
//			//for (auto&& e : graph[cent_id]) {
//			//	if (e.dst == from)continue;
//			//	if (oks[e.dst] != -1)continue;
//
//			//	dfs2(graph, e.dst, e.dst, e.src, oks,e.cost%mod,e.cost%mod,1);
//
//			//	for (auto&& l1 : lens1[e.dst]) {
//			//		int keta = l1.first.second;
//			//		long long int num = l1.first.first;
//
//			//		long long int need = (mod - num) / mod_pow(10, keta);
//			//		need%=mod;
//			//		auto it = lens2[e.dst].find(need);
//			//		if (it != lens2[e.dst].end()) {
//			//			ans -= l1.second*it->second;
//			//		}
//			//	}
//			//	lens1[e.dst].clear();
//			//	lens2[e.dst].clear();
//			//}
//
//			if (from != -1) {
//				centroid_edges[from].push_back(cent_id);
//			}
//			else {
//				fst_centroid = cent_id;
//			}
//			for (auto&& e : graph[cent_id]) {
//				if (e.dst == from)continue;
//				if (oks[e.dst] != -1)continue;
//				cent(graph, oks, e.dst, e.src, centroid_edges, fst_centroid, depth + 1, ch_nums);
//			}
//		}
//
//	public:
//
//		map<pair<int,int>,int>mp;
//
//		vector<map<pair<long long int,int>, long long int>>lens1;
//		vector<map<long long int, long long int>>lens2;
//		vector<vector<int>> centroid_graph;
//		vector<int>ts;
//		vector<int>parents;
//		vector<int>oks;
//		vector<int>anss;
//
//		//fst:root  snd:centroid_graph
//		void init(const Graph&g) {
//			lens1.resize(g.size());
//			lens2.resize(g.size());
//			oks = vector<int>(g.size(), -1);
//			int root = -1;
//			centroid_graph.resize(g.size());
//			parents = vector<int>(g.size(), -1);
//			ts=vector<int>(g.size(),-1);
//			anss=vector<int>(g.size(),100000);
//
//			vector<int>ch_nums(g.size());
//			cent(g, oks, 0, -1, centroid_graph, root, 0, ch_nums);
//
//			for (int i = 0; i < centroid_graph.size(); ++i) {
//				for (auto&& e : centroid_graph[i]) {
//					parents[e] = i;
//				}
//			}
//			return ;
//		}
//	}centroid;
//
//
//	void addEdge(Graph& g, int a, int b, long long int c) {
//		g[a].push_back(Edge{ a,b,c });
//		g[b].push_back(Edge{ b,a,c });
//	}
//}


//const int mod = 1000000007;
//struct Mod {
//public:
//	int num;
//	Mod() : Mod(0) { ; }
//	Mod(long long int n) : num((n % mod + mod) % mod) {
//		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
//	}
//	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
//	operator int() { return num; }
//};
//
//Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
//Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
//Mod operator+(const Mod a, const long long int  b) { return b + a; }
//Mod operator++(Mod &a) { return a + Mod(1); }
//Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
//Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
//Mod operator--(Mod &a) { return a - Mod(1); }
//Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
//Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
//Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
//Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
//Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
//Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
//Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
//Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
//Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
//Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
//Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
//Mod operator^(const Mod a, const int n) {
//	if (n == 0) return Mod(1);
//	Mod res = (a * a) ^ (n / 2);
//	if (n % 2) res = res * a;
//	return res;
//}
//Mod mod_pow(const Mod a, const long long  int n) {
//	if (n == 0) return Mod(1);
//	Mod res = mod_pow((a * a), (n / 2));
//	if (n % 2) res = res * a;
//	return res;
//}
//
////mod が素数の場合のみ　違う場合はextend euclid を用いる。
//Mod inv(const Mod a) { return a ^ (mod - 2); }
//Mod operator/(const Mod a, const Mod b) {
//	assert(b.num != 0);
//	return a * inv(b);
//}
//Mod operator/(const long long int a, const Mod b) {
//	return Mod(a) / b;
//}
//Mod operator/=(Mod &a, const Mod b) {
//	return a = a / b;
//}
//
//#define MAX_MOD_N 1024000
//
//Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
//void init(const int amax = MAX_MOD_N) {
//	fact[0] = Mod(1); factinv[0] = 1;
//	for (int i = 0; i < amax - 1; ++i) {
//		fact[i + 1] = fact[i] * Mod(i + 1);
//		factinv[i + 1] = factinv[i] / Mod(i + 1);
//	}
//}
//Mod comb(const int a, const int b) {
//	return fact[a] * factinv[b] * factinv[a - b];
//}
//
//vector<int>primes;
//void hurui(const int amax=3500) {
//	static bool flag = false;
//	if (flag)return;
//	vector<int>sos;
//	sos = vector<int>(amax + 1, true);
//	sos[0] = false; sos[1] = false;
//	for (int i = 2; i <= amax; ++i) {
//		if (sos[i]) {
//			for (int j = 2 * i; j <= amax; j += i)sos[j] = false;
//		}
//	}
//	for (int i = 0; i <= amax; ++i) {
//		if (sos[i]) {
//			primes.push_back(i);
//		}
//	}
//	flag = true;
//}
//
//
//struct query {
//	int u;
//	int v;
//	map<int,int>mp;
//};
//
//map<int, int>mk_mp(const int a) {
//	int rest(a);
//	map<int,int>as;
//	for (auto pr : primes) {
//		while (rest%pr == 0) {
//			as[pr]++;
//			rest /= pr;
//		}
//	}
//	if (rest!=1)as[rest]++;
//	return as;
//}
//
//#define Seg_Max_N (1<<18) 
//
//class Tree {
//public:
//	Tree(int V, int root) : V(V), root(root), cnum(V), place(V), id(V) {
//		T.resize(V);
//		for (int i = 0; i < MAXLOGV; i++) {
//			parent[i].resize(V);
//		}
//		depth.resize(V);
//	}
//	// uとvをつなぐ
//	// lcaを求めることが主目的なので無向グラフとしている
//	void unite(int u, int v) {
//		T[u].push_back(v);
//		T[v].push_back(u);
//	}
//	void unite(vector<vector<int>>&e) {
//		T = e;
//	}
//	// initする
//	// コンストラクタだけじゃなくてこれも呼ばないとlcaが求められないぞ
//	void init() {
//		dfs(root, 0, 0);
//		int id = 0;
//		getid(root, 0, id);
//	}
//	// uとvのlcaを求める
//	int lca(int u, int v) const {
//		if (depth[u] > depth[v]) swap(u, v);
//		for (int k = 0; k < MAXLOGV; k++) {
//			if ((depth[v] - depth[u]) >> k & 1) {
//				v = parent[k][v];
//			}
//		}
//		if (u == v) return u;
//		for (int k = MAXLOGV - 1; k >= 0; k--) {
//			if (parent[k][u] != parent[k][v]) {
//				u = parent[k][u];
//				v = parent[k][v];
//			}
//		}
//		return parent[0][u];
//	}
//	// uとvの距離を求める
//	// edgeを定義しないといけない時はこれじゃダメ
//	int dist(int u, int v) const {
//		int p = lca(u, v);
//		return (depth[u] - depth[p]) + (depth[v] - depth[p]);
//	}
//	int dfs(int v, int p, int d) {
//		parent[0][v] = p;
//		depth[v] = d;
//		cnum[v] = 0;
//		for (int i = 1; i < MAXLOGV; i++) {
//			parent[i][v] = parent[i - 1][parent[i - 1][v]];
//		}
//		for (int next : T[v]) {
//			if (next != p) cnum[v] += dfs(next, v, d + 1);
//		}
//		return cnum[v] + 1;
//	}
//
//	void dfs2(int v, int p, vector<vector<int>>&doubles, const vector<int>&nums) {
//		for (int next : T[v]) {
//			if (next != p) dfs2(next, v, doubles, nums);
//		}
//		doubles[0][v] = nums[v];
//		for (int j = 1; j < MAXLOGV; ++j) {
//			doubles[j][v] = min(doubles[j][v], doubles[j - 1][v]);
//		}
//		for (int j = 0; j < MAXLOGV - 1; ++j) {
//			doubles[j + 1][parent[j][v]] = min(doubles[j + 1][parent[j][v]], doubles[j][v]);
//		}
//	}
//	//ここでは親から距離2^iの部分木の最小値を求めている
//	vector<vector<int>>get_doubles(const vector<int>&nums) {
//		vector<vector<int>>doubles(MAXLOGV, vector<int>(V, 1e9));
//		dfs2(root, -1, doubles, nums);
//		return doubles;
//	}
//
//	void getid(const int v, const int p, int &nplace) {
//		place[v] = nplace;
//		id[nplace] = v;
//		nplace++;
//		for (int next : T[v]) {
//			if (next != p) getid(next, v, nplace);
//		}
//	}
//	static const int MAXLOGV = 25;
//	// グラフの隣接リスト表現
//	vector<vector<int> > T;
//	// 頂点の数
//	int V;
//	// 根ノードの番号
//	int root;
//
//	// 親ノード
//	vector<int> parent[MAXLOGV];
//	// 根からの深さ
//	vector<int> depth;
//
//	//子の数
//	vector<int>cnum;
//
//	//変換
//	vector<int>place;
//	vector<int>id;
//
//};
//
//vector<int>pas;
//void adfs(vector<pair<int, int>>&lrs, vector<int>&tos,const vector<vector<int>>&edges, const int now, const int from,int &id) {
//	tos[now]=id;
//	lrs[tos[now]].first=id++;
//	for (auto e : edges[now]) {
//		if (e == from) {
//			pas[now] = from;
//			continue;
//		}
//		adfs(lrs,tos,edges,e,now,id);
//	}
//	lrs[tos[now]].second=id;
//}
//
//vector<pair<int, int>>get_lrs(vector<int>&tos,const vector<vector<int>>&edges, const int root) {
//	pas.resize(tos.size());pas[0]=-1;
//	vector<pair<int,int>>lrs(edges.size());
//	int id=0;
//	adfs(lrs,tos,edges,0,-1,id);
//	return lrs;
//}


ld memo[101][101][101][3][3];

ld solve(int a, int b, int c, int d, int e) ;

ld solve(vector<int>v, int joker, int player) {
	if(!(v[0]>=0&&v[1]>=0&&v[2]>=0&&joker>=0&&joker<=2&&player>=0&&player<=2))return 0;
	if (memo[v[0]][v[1]][v[2]][joker][player] < -0.5) {
		if (v[0] == 0 && v[1] == 0 && v[2] == 0) {
			if (joker == 1) {
				memo[v[0]][v[1]][v[2]][joker][player]=0;
			}
			else {
				memo[v[0]][v[1]][v[2]][joker][player]=1;
			}
		}
		else {
			const int n_player=(player+1)%3;
			// A no card
			if (v[0] == 0 && v[2] == 0 && joker != 0) {
				if (player == 0) {
					memo[v[0]][v[1]][v[2]][joker][player] = solve(v, joker, n_player);
				}
				else {
					const int drawn_player=(player^3);
					ld ans = 0;
					if (drawn_player == 2) {
						ans+=(joker==drawn_player)*solve(v,player, n_player);
						ans+=v[1]*solve(v[0],v[1]-1,v[2],joker, n_player);

						ans/=(joker==2)+v[1];
					}
					else {
						assert(v[1]);
						ans=solve(v[0],v[1]-1,v[2],joker,n_player);
					}

					memo[v[0]][v[1]][v[2]][joker][player]=ans;
				}
			}
			// B no card
			else if (v[0] == 0 && v[1] == 0 && joker != 1) {
				memo[v[0]][v[1]][v[2]][joker][player] = 1;
			}
			// C no card
			else if (v[1] == 0 && v[2] == 0 && joker != 2) {
				if (player == 2) {
					memo[v[0]][v[1]][v[2]][joker][player]=solve(v,joker,n_player);
				}
				else {
					const int drawn_player = (player ^ 1);
					ld ans = 0;
					if (drawn_player==0) {
						ans += (joker == drawn_player)*solve(v, player ,n_player);
						ans += v[0]*solve(v[0]-1, v[1], v[2], joker, n_player);

						assert((joker==0)+v[0]>=1);
						ans /= (joker == 0) + v[0];
					}
					else {
						assert(v[0]);
						ans = solve(v[0]-1, v[1], v[2], joker, n_player);
					}

					memo[v[0]][v[1]][v[2]][joker][player] = ans;
				}
			}
			else {
				ld ans=0;
				int drawn_player=(player+2)%3;
				if (player == 0) {
					ans+=v[1]*solve(v[0]+1,v[1]-1,v[2],joker,n_player);
					ans+=v[2]*solve(v[0],v[1],v[2]-1,joker,n_player);
					ans+=(joker==2)*solve(v[0],v[1],v[2],0,n_player);

					assert(v[1]+v[2]+(joker==2)>=1);
					ans/=v[1]+v[2]+(joker==2);
				}
				else if (player == 1) {
					ans+=v[2]*solve(v[0],v[1]+1,v[2]-1,joker,n_player);
					ans+=v[0]*solve(v[0]-1,v[1],v[2],joker,n_player);
					ans+=(joker==0)*solve(v[0],v[1],v[2],1,n_player);

					assert(v[2]+v[0]+(joker==0)>=1);
					ans/=v[2]+v[0]+(joker==0);
				}
				else if (player == 2) {
					if (v[1]) {
						ans=solve(v[0],v[1]-1,v[2],joker,n_player);
					}
					else if (v[0]) {
						ans=solve(v[0]-1,v[1],v[2]+1,joker,n_player);
					}
					else {
						assert(joker==1);
						ans=solve(v,player,n_player);
					}
				}
				memo[v[0]][v[1]][v[2]][joker][player] = ans;
			}
		}
	}
	return memo[v[0]][v[1]][v[2]][joker][player];
}

ld solve(int a, int b, int c, int d, int e) {
	return solve(vector<int>{a, b, c},d,e);
}

int main()
{

	int AB=0,BC=0,CA=0;
	int joker=-1;

	for (int i = 0; i < 101; ++i) {
		for (int j = 0; j < 101; ++j) {
			for (int k = 0; k < 101; ++k) {
				for (int l = 0; l < 3; ++l) {
					for (int m = 0; m < 3; ++m) {
						memo[i][j][k][l][m]=-1;
					}
				}
			}
		}
	}
	{
		int N; cin >> N;

		vector<vector<int>>nums(3, vector<int>(101));
		for (int i = 0; i < 3; ++i) {
			int m; cin >> m;
			map<int, int>mp;
			while (m--) {
				int a; cin >> a;
				mp[a]++;
			}
			for (auto m : mp) {
				if (m.second % 2)nums[i][m.first]++;
			}
		}

		for (int i = 0; i <= N; ++i) {
			if (i == 0) {
				for (int j = 0; j < 3; ++j) {
					if (nums[j][i]) {
						joker=j;
					}
				}
			}
			else {
				if (nums[0][i] && nums[1][i]) {
					AB++;
				}
				else if (nums[1][i] && nums[2][i]) {
					BC++;
				}
				else if (nums[2][i] && nums[0][i]) {
					CA++;
				}
			}
		}
	}

	ld ans=solve(AB,BC,CA,joker,0);

	cout<<setprecision(10)<<fixed<<double(ans)<<endl;
	
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 148208
final_rank: 4

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = __float128;
const ld eps = 1e-9;


//namespace cent {
//
//	struct Edge {
//		int src;
//		int dst;
//		long long int cost;
//	};
//	using Graph = vector<vector<Edge>>;
//
//	class Centroid {
//	private:
//		int dfs(const Graph&g, const int now, const int from, vector<int>&ch_nums, const vector<int>&oks) {
//			int sum = 1;
//			for (auto &&e : g[now]) {
//				if (e.dst == from || oks[e.dst] != -1)continue;
//				else {
//					sum += dfs(g, e.dst, e.src, ch_nums, oks);
//				}
//			}
//			return ch_nums[now] = sum;
//		}
//
//		int find_centroid(const int asize, const vector<vector<Edge>>&graph, const int pre_root, const int pre_from, const vector<int>&ch_nums, const vector<int>&oks) {
//			for (auto&& e : graph[pre_root]) {
//				if (e.dst == pre_from)continue;
//				if (oks[e.dst] != -1)continue;
//				if (ch_nums[e.dst]>asize / 2)return find_centroid(asize, graph, e.dst, e.src, ch_nums, oks);
//			}
//			return pre_root;
//		}
//
//		void dfs2(const Graph&g, const int root,const int now, const int from, const vector<int>&oks,int depth) {
//			mp[make_pair(root,now)]=depth;
//			for (auto &&e : g[now]) {
//				if (e.dst == from || oks[e.dst] != -1)continue;
//				else {
//					dfs2(g,root,e.dst,e.src,oks,depth+1);
//				}
//			}
//		};
//
//
//		void cent(const vector<vector<Edge>>&graph, vector<int>&oks, const int root, const int from, vector<vector<int>>&centroid_edges, int& fst_centroid, int depth, vector<int>&ch_nums) {
//			dfs(graph, root, from, ch_nums, oks);
//
//			int cent_id = find_centroid(ch_nums[root], graph, root, from, ch_nums, oks);
//
//
//			dfs2(graph,cent_id,cent_id,-1,oks,0);
//			lens1[cent_id][make_pair(0,0)]--;
//			lens2[cent_id][0]--;
//
//
//			oks[cent_id] = depth;
//
//			//for (auto&& e : graph[cent_id]) {
//			//	if (e.dst == from)continue;
//			//	if (oks[e.dst] != -1)continue;
//
//			//	dfs2(graph, e.dst, e.dst, e.src, oks,e.cost%mod,e.cost%mod,1);
//
//			//	for (auto&& l1 : lens1[e.dst]) {
//			//		int keta = l1.first.second;
//			//		long long int num = l1.first.first;
//
//			//		long long int need = (mod - num) / mod_pow(10, keta);
//			//		need%=mod;
//			//		auto it = lens2[e.dst].find(need);
//			//		if (it != lens2[e.dst].end()) {
//			//			ans -= l1.second*it->second;
//			//		}
//			//	}
//			//	lens1[e.dst].clear();
//			//	lens2[e.dst].clear();
//			//}
//
//			if (from != -1) {
//				centroid_edges[from].push_back(cent_id);
//			}
//			else {
//				fst_centroid = cent_id;
//			}
//			for (auto&& e : graph[cent_id]) {
//				if (e.dst == from)continue;
//				if (oks[e.dst] != -1)continue;
//				cent(graph, oks, e.dst, e.src, centroid_edges, fst_centroid, depth + 1, ch_nums);
//			}
//		}
//
//	public:
//
//		map<pair<int,int>,int>mp;
//
//		vector<map<pair<long long int,int>, long long int>>lens1;
//		vector<map<long long int, long long int>>lens2;
//		vector<vector<int>> centroid_graph;
//		vector<int>ts;
//		vector<int>parents;
//		vector<int>oks;
//		vector<int>anss;
//
//		//fst:root  snd:centroid_graph
//		void init(const Graph&g) {
//			lens1.resize(g.size());
//			lens2.resize(g.size());
//			oks = vector<int>(g.size(), -1);
//			int root = -1;
//			centroid_graph.resize(g.size());
//			parents = vector<int>(g.size(), -1);
//			ts=vector<int>(g.size(),-1);
//			anss=vector<int>(g.size(),100000);
//
//			vector<int>ch_nums(g.size());
//			cent(g, oks, 0, -1, centroid_graph, root, 0, ch_nums);
//
//			for (int i = 0; i < centroid_graph.size(); ++i) {
//				for (auto&& e : centroid_graph[i]) {
//					parents[e] = i;
//				}
//			}
//			return ;
//		}
//	}centroid;
//
//
//	void addEdge(Graph& g, int a, int b, long long int c) {
//		g[a].push_back(Edge{ a,b,c });
//		g[b].push_back(Edge{ b,a,c });
//	}
//}


//const int mod = 1000000007;
//struct Mod {
//public:
//	int num;
//	Mod() : Mod(0) { ; }
//	Mod(long long int n) : num((n % mod + mod) % mod) {
//		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
//	}
//	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
//	operator int() { return num; }
//};
//
//Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
//Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
//Mod operator+(const Mod a, const long long int  b) { return b + a; }
//Mod operator++(Mod &a) { return a + Mod(1); }
//Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
//Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
//Mod operator--(Mod &a) { return a - Mod(1); }
//Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
//Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
//Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
//Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
//Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
//Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
//Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
//Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
//Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
//Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
//Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
//Mod operator^(const Mod a, const int n) {
//	if (n == 0) return Mod(1);
//	Mod res = (a * a) ^ (n / 2);
//	if (n % 2) res = res * a;
//	return res;
//}
//Mod mod_pow(const Mod a, const long long  int n) {
//	if (n == 0) return Mod(1);
//	Mod res = mod_pow((a * a), (n / 2));
//	if (n % 2) res = res * a;
//	return res;
//}
//
////mod が素数の場合のみ　違う場合はextend euclid を用いる。
//Mod inv(const Mod a) { return a ^ (mod - 2); }
//Mod operator/(const Mod a, const Mod b) {
//	assert(b.num != 0);
//	return a * inv(b);
//}
//Mod operator/(const long long int a, const Mod b) {
//	return Mod(a) / b;
//}
//Mod operator/=(Mod &a, const Mod b) {
//	return a = a / b;
//}
//
//#define MAX_MOD_N 1024000
//
//Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
//void init(const int amax = MAX_MOD_N) {
//	fact[0] = Mod(1); factinv[0] = 1;
//	for (int i = 0; i < amax - 1; ++i) {
//		fact[i + 1] = fact[i] * Mod(i + 1);
//		factinv[i + 1] = factinv[i] / Mod(i + 1);
//	}
//}
//Mod comb(const int a, const int b) {
//	return fact[a] * factinv[b] * factinv[a - b];
//}
//
//vector<int>primes;
//void hurui(const int amax=3500) {
//	static bool flag = false;
//	if (flag)return;
//	vector<int>sos;
//	sos = vector<int>(amax + 1, true);
//	sos[0] = false; sos[1] = false;
//	for (int i = 2; i <= amax; ++i) {
//		if (sos[i]) {
//			for (int j = 2 * i; j <= amax; j += i)sos[j] = false;
//		}
//	}
//	for (int i = 0; i <= amax; ++i) {
//		if (sos[i]) {
//			primes.push_back(i);
//		}
//	}
//	flag = true;
//}
//
//
//struct query {
//	int u;
//	int v;
//	map<int,int>mp;
//};
//
//map<int, int>mk_mp(const int a) {
//	int rest(a);
//	map<int,int>as;
//	for (auto pr : primes) {
//		while (rest%pr == 0) {
//			as[pr]++;
//			rest /= pr;
//		}
//	}
//	if (rest!=1)as[rest]++;
//	return as;
//}
//
//#define Seg_Max_N (1<<18) 
//
//class Tree {
//public:
//	Tree(int V, int root) : V(V), root(root), cnum(V), place(V), id(V) {
//		T.resize(V);
//		for (int i = 0; i < MAXLOGV; i++) {
//			parent[i].resize(V);
//		}
//		depth.resize(V);
//	}
//	// uとvをつなぐ
//	// lcaを求めることが主目的なので無向グラフとしている
//	void unite(int u, int v) {
//		T[u].push_back(v);
//		T[v].push_back(u);
//	}
//	void unite(vector<vector<int>>&e) {
//		T = e;
//	}
//	// initする
//	// コンストラクタだけじゃなくてこれも呼ばないとlcaが求められないぞ
//	void init() {
//		dfs(root, 0, 0);
//		int id = 0;
//		getid(root, 0, id);
//	}
//	// uとvのlcaを求める
//	int lca(int u, int v) const {
//		if (depth[u] > depth[v]) swap(u, v);
//		for (int k = 0; k < MAXLOGV; k++) {
//			if ((depth[v] - depth[u]) >> k & 1) {
//				v = parent[k][v];
//			}
//		}
//		if (u == v) return u;
//		for (int k = MAXLOGV - 1; k >= 0; k--) {
//			if (parent[k][u] != parent[k][v]) {
//				u = parent[k][u];
//				v = parent[k][v];
//			}
//		}
//		return parent[0][u];
//	}
//	// uとvの距離を求める
//	// edgeを定義しないといけない時はこれじゃダメ
//	int dist(int u, int v) const {
//		int p = lca(u, v);
//		return (depth[u] - depth[p]) + (depth[v] - depth[p]);
//	}
//	int dfs(int v, int p, int d) {
//		parent[0][v] = p;
//		depth[v] = d;
//		cnum[v] = 0;
//		for (int i = 1; i < MAXLOGV; i++) {
//			parent[i][v] = parent[i - 1][parent[i - 1][v]];
//		}
//		for (int next : T[v]) {
//			if (next != p) cnum[v] += dfs(next, v, d + 1);
//		}
//		return cnum[v] + 1;
//	}
//
//	void dfs2(int v, int p, vector<vector<int>>&doubles, const vector<int>&nums) {
//		for (int next : T[v]) {
//			if (next != p) dfs2(next, v, doubles, nums);
//		}
//		doubles[0][v] = nums[v];
//		for (int j = 1; j < MAXLOGV; ++j) {
//			doubles[j][v] = min(doubles[j][v], doubles[j - 1][v]);
//		}
//		for (int j = 0; j < MAXLOGV - 1; ++j) {
//			doubles[j + 1][parent[j][v]] = min(doubles[j + 1][parent[j][v]], doubles[j][v]);
//		}
//	}
//	//ここでは親から距離2^iの部分木の最小値を求めている
//	vector<vector<int>>get_doubles(const vector<int>&nums) {
//		vector<vector<int>>doubles(MAXLOGV, vector<int>(V, 1e9));
//		dfs2(root, -1, doubles, nums);
//		return doubles;
//	}
//
//	void getid(const int v, const int p, int &nplace) {
//		place[v] = nplace;
//		id[nplace] = v;
//		nplace++;
//		for (int next : T[v]) {
//			if (next != p) getid(next, v, nplace);
//		}
//	}
//	static const int MAXLOGV = 25;
//	// グラフの隣接リスト表現
//	vector<vector<int> > T;
//	// 頂点の数
//	int V;
//	// 根ノードの番号
//	int root;
//
//	// 親ノード
//	vector<int> parent[MAXLOGV];
//	// 根からの深さ
//	vector<int> depth;
//
//	//子の数
//	vector<int>cnum;
//
//	//変換
//	vector<int>place;
//	vector<int>id;
//
//};
//
//vector<int>pas;
//void adfs(vector<pair<int, int>>&lrs, vector<int>&tos,const vector<vector<int>>&edges, const int now, const int from,int &id) {
//	tos[now]=id;
//	lrs[tos[now]].first=id++;
//	for (auto e : edges[now]) {
//		if (e == from) {
//			pas[now] = from;
//			continue;
//		}
//		adfs(lrs,tos,edges,e,now,id);
//	}
//	lrs[tos[now]].second=id;
//}
//
//vector<pair<int, int>>get_lrs(vector<int>&tos,const vector<vector<int>>&edges, const int root) {
//	pas.resize(tos.size());pas[0]=-1;
//	vector<pair<int,int>>lrs(edges.size());
//	int id=0;
//	adfs(lrs,tos,edges,0,-1,id);
//	return lrs;
//}


ld memo[101][101][101][3][3];

ld solve(int a, int b, int c, int d, int e) ;

ld solve(vector<int>v, int joker, int player) {
	if(!(v[0]>=0&&v[1]>=0&&v[2]>=0&&joker>=0&&joker<=2&&player>=0&&player<=2))return 0;
	if (memo[v[0]][v[1]][v[2]][joker][player] < -0.5) {
		if (v[0] == 0 && v[1] == 0 && v[2] == 0) {
			if (joker == 1) {
				memo[v[0]][v[1]][v[2]][joker][player]=0;
			}
			else {
				memo[v[0]][v[1]][v[2]][joker][player]=1;
			}
		}
		else {
			const int n_player=(player+1)%3;
			// A no card
			if (v[0] == 0 && v[2] == 0 && joker != 0) {
				if (player == 0) {
					memo[v[0]][v[1]][v[2]][joker][player] = solve(v, joker, n_player);
				}
				else {
					const int drawn_player=(player^3);
					ld ans = 0;
					if (drawn_player == 2) {
						ans+=(joker==drawn_player)*solve(v,1, n_player);
						ans+=v[1]*solve(v[0],v[1]-1,v[2],2, n_player);

						ans/=(joker==2)+v[1];
					}
					else {
						assert(v[1]);
						ans=solve(v[0],v[1]-1,v[2],joker,n_player);
					}

					memo[v[0]][v[1]][v[2]][joker][player]=ans;
				}
			}
			// B no card
			else if (v[0] == 0 && v[1] == 0 && joker != 1) {
				memo[v[0]][v[1]][v[2]][joker][player] = 1;
			}
			// C no card
			else if (v[1] == 0 && v[2] == 0 && joker != 2) {
				if (player == 2) {
					memo[v[0]][v[1]][v[2]][joker][player]=solve(v,joker,n_player);
				}
				else {
					const int drawn_player = (player ^ 1);
					ld ans = 0;
					if (drawn_player==0) {
						ans += (joker == drawn_player)*solve(v, player ,n_player);
						ans += v[0]*solve(v[0]-1, v[1], v[2], joker, n_player);

						assert((joker==0)+v[0]>=1);
						ans /= (joker == 0) + v[0];
					}
					else {
						assert(v[0]);
						ans = solve(v[0]-1, v[1], v[2], joker, n_player);
					}

					memo[v[0]][v[1]][v[2]][joker][player] = ans;
				}
			}
			else {
				ld ans=0;
				int drawn_player=(player+2)%3;
				if (player == 0) {
					ans+=v[1]*solve(v[0]+1,v[1]-1,v[2],joker,n_player);
					ans+=v[2]*solve(v[0],v[1],v[2]-1,joker,n_player);
					ans+=(joker==2)*solve(v[0],v[1],v[2],0,n_player);

					assert(v[1]+v[2]+(joker==2)>=1);
					ans/=v[1]+v[2]+(joker==2);
				}
				else if (player == 1) {
					ans+=v[2]*solve(v[0],v[1]+1,v[2]-1,joker,n_player);
					ans+=v[0]*solve(v[0]-1,v[1],v[2],joker,n_player);
					ans+=(joker==0)*solve(v[0],v[1],v[2],1,n_player);

					assert(v[2]+v[0]+(joker==0)>=1);
					ans/=v[2]+v[0]+(joker==0);
				}
				else if (player == 2) {
					if (v[1]) {
						ans=solve(v[0],v[1]-1,v[2],joker,n_player);
					}
					else if (v[0]) {
						ans=solve(v[0]-1,v[1],v[2]+1,joker,n_player);
					}
					else {
						ans=solve(v,player,n_player);
					}
				}
				memo[v[0]][v[1]][v[2]][joker][player] = ans;
			}
		}
	}
	return memo[v[0]][v[1]][v[2]][joker][player];
}

ld solve(int a, int b, int c, int d, int e) {
	return solve(vector<int>{a, b, c},d,e);
}

int main()
{

	int AB=0,BC=0,CA=0;
	int joker=-1;

	for (int i = 0; i < 101; ++i) {
		for (int j = 0; j < 101; ++j) {
			for (int k = 0; k < 101; ++k) {
				for (int l = 0; l < 3; ++l) {
					for (int m = 0; m < 3; ++m) {
						memo[i][j][k][l][m]=-1;
					}
				}
			}
		}
	}
	{
		int N; cin >> N;

		vector<vector<int>>nums(3, vector<int>(101));
		for (int i = 0; i < 3; ++i) {
			int m; cin >> m;
			map<int, int>mp;
			while (m--) {
				int a; cin >> a;
				mp[a]++;
			}
			for (auto m : mp) {
				if (m.second % 2)nums[i][m.first]++;
			}
		}

		for (int i = 0; i <= N; ++i) {
			if (i == 0) {
				for (int j = 0; j < 3; ++j) {
					if (nums[j][i]) {
						joker=j;
					}
				}
			}
			else {
				if (nums[0][i] && nums[1][i]) {
					AB++;
				}
				else if (nums[1][i] && nums[2][i]) {
					BC++;
				}
				else if (nums[2][i] && nums[0][i]) {
					CA++;
				}
			}
		}
	}

	ld ans=solve(AB,BC,CA,joker,0);

	cout<<setprecision(10)<<fixed<<double(ans)<<endl;
	
	return 0;
}
accuracy: 0.11904761904761904
time_ms: 40
memory_kb: 148148
final_rank: 7

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;


//namespace cent {
//
//	struct Edge {
//		int src;
//		int dst;
//		long long int cost;
//	};
//	using Graph = vector<vector<Edge>>;
//
//	class Centroid {
//	private:
//		int dfs(const Graph&g, const int now, const int from, vector<int>&ch_nums, const vector<int>&oks) {
//			int sum = 1;
//			for (auto &&e : g[now]) {
//				if (e.dst == from || oks[e.dst] != -1)continue;
//				else {
//					sum += dfs(g, e.dst, e.src, ch_nums, oks);
//				}
//			}
//			return ch_nums[now] = sum;
//		}
//
//		int find_centroid(const int asize, const vector<vector<Edge>>&graph, const int pre_root, const int pre_from, const vector<int>&ch_nums, const vector<int>&oks) {
//			for (auto&& e : graph[pre_root]) {
//				if (e.dst == pre_from)continue;
//				if (oks[e.dst] != -1)continue;
//				if (ch_nums[e.dst]>asize / 2)return find_centroid(asize, graph, e.dst, e.src, ch_nums, oks);
//			}
//			return pre_root;
//		}
//
//		void dfs2(const Graph&g, const int root,const int now, const int from, const vector<int>&oks,int depth) {
//			mp[make_pair(root,now)]=depth;
//			for (auto &&e : g[now]) {
//				if (e.dst == from || oks[e.dst] != -1)continue;
//				else {
//					dfs2(g,root,e.dst,e.src,oks,depth+1);
//				}
//			}
//		};
//
//
//		void cent(const vector<vector<Edge>>&graph, vector<int>&oks, const int root, const int from, vector<vector<int>>&centroid_edges, int& fst_centroid, int depth, vector<int>&ch_nums) {
//			dfs(graph, root, from, ch_nums, oks);
//
//			int cent_id = find_centroid(ch_nums[root], graph, root, from, ch_nums, oks);
//
//
//			dfs2(graph,cent_id,cent_id,-1,oks,0);
//			lens1[cent_id][make_pair(0,0)]--;
//			lens2[cent_id][0]--;
//
//
//			oks[cent_id] = depth;
//
//			//for (auto&& e : graph[cent_id]) {
//			//	if (e.dst == from)continue;
//			//	if (oks[e.dst] != -1)continue;
//
//			//	dfs2(graph, e.dst, e.dst, e.src, oks,e.cost%mod,e.cost%mod,1);
//
//			//	for (auto&& l1 : lens1[e.dst]) {
//			//		int keta = l1.first.second;
//			//		long long int num = l1.first.first;
//
//			//		long long int need = (mod - num) / mod_pow(10, keta);
//			//		need%=mod;
//			//		auto it = lens2[e.dst].find(need);
//			//		if (it != lens2[e.dst].end()) {
//			//			ans -= l1.second*it->second;
//			//		}
//			//	}
//			//	lens1[e.dst].clear();
//			//	lens2[e.dst].clear();
//			//}
//
//			if (from != -1) {
//				centroid_edges[from].push_back(cent_id);
//			}
//			else {
//				fst_centroid = cent_id;
//			}
//			for (auto&& e : graph[cent_id]) {
//				if (e.dst == from)continue;
//				if (oks[e.dst] != -1)continue;
//				cent(graph, oks, e.dst, e.src, centroid_edges, fst_centroid, depth + 1, ch_nums);
//			}
//		}
//
//	public:
//
//		map<pair<int,int>,int>mp;
//
//		vector<map<pair<long long int,int>, long long int>>lens1;
//		vector<map<long long int, long long int>>lens2;
//		vector<vector<int>> centroid_graph;
//		vector<int>ts;
//		vector<int>parents;
//		vector<int>oks;
//		vector<int>anss;
//
//		//fst:root  snd:centroid_graph
//		void init(const Graph&g) {
//			lens1.resize(g.size());
//			lens2.resize(g.size());
//			oks = vector<int>(g.size(), -1);
//			int root = -1;
//			centroid_graph.resize(g.size());
//			parents = vector<int>(g.size(), -1);
//			ts=vector<int>(g.size(),-1);
//			anss=vector<int>(g.size(),100000);
//
//			vector<int>ch_nums(g.size());
//			cent(g, oks, 0, -1, centroid_graph, root, 0, ch_nums);
//
//			for (int i = 0; i < centroid_graph.size(); ++i) {
//				for (auto&& e : centroid_graph[i]) {
//					parents[e] = i;
//				}
//			}
//			return ;
//		}
//	}centroid;
//
//
//	void addEdge(Graph& g, int a, int b, long long int c) {
//		g[a].push_back(Edge{ a,b,c });
//		g[b].push_back(Edge{ b,a,c });
//	}
//}


//const int mod = 1000000007;
//struct Mod {
//public:
//	int num;
//	Mod() : Mod(0) { ; }
//	Mod(long long int n) : num((n % mod + mod) % mod) {
//		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
//	}
//	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
//	operator int() { return num; }
//};
//
//Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
//Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
//Mod operator+(const Mod a, const long long int  b) { return b + a; }
//Mod operator++(Mod &a) { return a + Mod(1); }
//Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
//Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
//Mod operator--(Mod &a) { return a - Mod(1); }
//Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
//Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
//Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
//Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
//Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
//Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
//Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
//Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
//Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
//Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
//Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
//Mod operator^(const Mod a, const int n) {
//	if (n == 0) return Mod(1);
//	Mod res = (a * a) ^ (n / 2);
//	if (n % 2) res = res * a;
//	return res;
//}
//Mod mod_pow(const Mod a, const long long  int n) {
//	if (n == 0) return Mod(1);
//	Mod res = mod_pow((a * a), (n / 2));
//	if (n % 2) res = res * a;
//	return res;
//}
//
////mod が素数の場合のみ　違う場合はextend euclid を用いる。
//Mod inv(const Mod a) { return a ^ (mod - 2); }
//Mod operator/(const Mod a, const Mod b) {
//	assert(b.num != 0);
//	return a * inv(b);
//}
//Mod operator/(const long long int a, const Mod b) {
//	return Mod(a) / b;
//}
//Mod operator/=(Mod &a, const Mod b) {
//	return a = a / b;
//}
//
//#define MAX_MOD_N 1024000
//
//Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
//void init(const int amax = MAX_MOD_N) {
//	fact[0] = Mod(1); factinv[0] = 1;
//	for (int i = 0; i < amax - 1; ++i) {
//		fact[i + 1] = fact[i] * Mod(i + 1);
//		factinv[i + 1] = factinv[i] / Mod(i + 1);
//	}
//}
//Mod comb(const int a, const int b) {
//	return fact[a] * factinv[b] * factinv[a - b];
//}
//
//vector<int>primes;
//void hurui(const int amax=3500) {
//	static bool flag = false;
//	if (flag)return;
//	vector<int>sos;
//	sos = vector<int>(amax + 1, true);
//	sos[0] = false; sos[1] = false;
//	for (int i = 2; i <= amax; ++i) {
//		if (sos[i]) {
//			for (int j = 2 * i; j <= amax; j += i)sos[j] = false;
//		}
//	}
//	for (int i = 0; i <= amax; ++i) {
//		if (sos[i]) {
//			primes.push_back(i);
//		}
//	}
//	flag = true;
//}
//
//
//struct query {
//	int u;
//	int v;
//	map<int,int>mp;
//};
//
//map<int, int>mk_mp(const int a) {
//	int rest(a);
//	map<int,int>as;
//	for (auto pr : primes) {
//		while (rest%pr == 0) {
//			as[pr]++;
//			rest /= pr;
//		}
//	}
//	if (rest!=1)as[rest]++;
//	return as;
//}
//
//#define Seg_Max_N (1<<18) 
//
//class Tree {
//public:
//	Tree(int V, int root) : V(V), root(root), cnum(V), place(V), id(V) {
//		T.resize(V);
//		for (int i = 0; i < MAXLOGV; i++) {
//			parent[i].resize(V);
//		}
//		depth.resize(V);
//	}
//	// uとvをつなぐ
//	// lcaを求めることが主目的なので無向グラフとしている
//	void unite(int u, int v) {
//		T[u].push_back(v);
//		T[v].push_back(u);
//	}
//	void unite(vector<vector<int>>&e) {
//		T = e;
//	}
//	// initする
//	// コンストラクタだけじゃなくてこれも呼ばないとlcaが求められないぞ
//	void init() {
//		dfs(root, 0, 0);
//		int id = 0;
//		getid(root, 0, id);
//	}
//	// uとvのlcaを求める
//	int lca(int u, int v) const {
//		if (depth[u] > depth[v]) swap(u, v);
//		for (int k = 0; k < MAXLOGV; k++) {
//			if ((depth[v] - depth[u]) >> k & 1) {
//				v = parent[k][v];
//			}
//		}
//		if (u == v) return u;
//		for (int k = MAXLOGV - 1; k >= 0; k--) {
//			if (parent[k][u] != parent[k][v]) {
//				u = parent[k][u];
//				v = parent[k][v];
//			}
//		}
//		return parent[0][u];
//	}
//	// uとvの距離を求める
//	// edgeを定義しないといけない時はこれじゃダメ
//	int dist(int u, int v) const {
//		int p = lca(u, v);
//		return (depth[u] - depth[p]) + (depth[v] - depth[p]);
//	}
//	int dfs(int v, int p, int d) {
//		parent[0][v] = p;
//		depth[v] = d;
//		cnum[v] = 0;
//		for (int i = 1; i < MAXLOGV; i++) {
//			parent[i][v] = parent[i - 1][parent[i - 1][v]];
//		}
//		for (int next : T[v]) {
//			if (next != p) cnum[v] += dfs(next, v, d + 1);
//		}
//		return cnum[v] + 1;
//	}
//
//	void dfs2(int v, int p, vector<vector<int>>&doubles, const vector<int>&nums) {
//		for (int next : T[v]) {
//			if (next != p) dfs2(next, v, doubles, nums);
//		}
//		doubles[0][v] = nums[v];
//		for (int j = 1; j < MAXLOGV; ++j) {
//			doubles[j][v] = min(doubles[j][v], doubles[j - 1][v]);
//		}
//		for (int j = 0; j < MAXLOGV - 1; ++j) {
//			doubles[j + 1][parent[j][v]] = min(doubles[j + 1][parent[j][v]], doubles[j][v]);
//		}
//	}
//	//ここでは親から距離2^iの部分木の最小値を求めている
//	vector<vector<int>>get_doubles(const vector<int>&nums) {
//		vector<vector<int>>doubles(MAXLOGV, vector<int>(V, 1e9));
//		dfs2(root, -1, doubles, nums);
//		return doubles;
//	}
//
//	void getid(const int v, const int p, int &nplace) {
//		place[v] = nplace;
//		id[nplace] = v;
//		nplace++;
//		for (int next : T[v]) {
//			if (next != p) getid(next, v, nplace);
//		}
//	}
//	static const int MAXLOGV = 25;
//	// グラフの隣接リスト表現
//	vector<vector<int> > T;
//	// 頂点の数
//	int V;
//	// 根ノードの番号
//	int root;
//
//	// 親ノード
//	vector<int> parent[MAXLOGV];
//	// 根からの深さ
//	vector<int> depth;
//
//	//子の数
//	vector<int>cnum;
//
//	//変換
//	vector<int>place;
//	vector<int>id;
//
//};
//
//vector<int>pas;
//void adfs(vector<pair<int, int>>&lrs, vector<int>&tos,const vector<vector<int>>&edges, const int now, const int from,int &id) {
//	tos[now]=id;
//	lrs[tos[now]].first=id++;
//	for (auto e : edges[now]) {
//		if (e == from) {
//			pas[now] = from;
//			continue;
//		}
//		adfs(lrs,tos,edges,e,now,id);
//	}
//	lrs[tos[now]].second=id;
//}
//
//vector<pair<int, int>>get_lrs(vector<int>&tos,const vector<vector<int>>&edges, const int root) {
//	pas.resize(tos.size());pas[0]=-1;
//	vector<pair<int,int>>lrs(edges.size());
//	int id=0;
//	adfs(lrs,tos,edges,0,-1,id);
//	return lrs;
//}


ld memo[101][101][101][3][3];

ld solve(int a, int b, int c, int d, int e) ;

ld solve(vector<int>v, int joker, int player) {
	if(!(v[0]>=0&&v[1]>=0&&v[2]>=0&&joker>=0&&joker<=2&&player>=0&&player<=2))return 0;
	if (memo[v[0]][v[1]][v[2]][joker][player] < -0.5) {
		if (v[0] == 0 && v[1] == 0 && v[2] == 0) {
			if (joker == 1) {
				memo[v[0]][v[1]][v[2]][joker][player]=0;
			}
			else {
				memo[v[0]][v[1]][v[2]][joker][player]=1;
			}
		}
		else {
			const int n_player=(player+1)%3;
			// A no card
			if (v[0] == 0 && v[2] == 0 && joker != 0) {
				if (player == 0) {
					memo[v[0]][v[1]][v[2]][joker][player] = solve(v, joker, n_player);
				}
				else {
					const int drawn_player=(player^3);
					ld ans = 0;
					if (drawn_player == 2) {
						ans+=(joker==drawn_player)*solve(v,1, n_player);
						ans+=v[1]*solve(v[0],v[1]-1,v[2],2, n_player);

						ans/=(joker==2)+v[1];
					}
					else {
						assert(v[1]);
						ans=solve(v[0],v[1]-1,v[2],joker,n_player);
					}

					memo[v[0]][v[1]][v[2]][joker][player]=ans;
				}
			}
			// B no card
			else if (v[0] == 0 && v[1] == 0 && joker != 1) {
				memo[v[0]][v[1]][v[2]][joker][player] = 1;
			}
			// C no card
			else if (v[1] == 0 && v[2] == 0 && joker != 2) {
				if (player == 2) {
					memo[v[0]][v[1]][v[2]][joker][player]=solve(v,joker,n_player);
				}
				else {
					const int drawn_player = (player ^ 1);
					ld ans = 0;
					if (drawn_player==0) {
						ans += (joker == drawn_player)*solve(v, player ,n_player);
						ans += v[0]*solve(v[0]-1, v[1], v[2], joker, n_player);

						assert((joker==0)+v[0]>=1);
						ans /= (joker == 0) + v[0];
					}
					else {
						assert(v[0]);
						ans = solve(v[0]-1, v[1], v[2], joker, n_player);
					}

					memo[v[0]][v[1]][v[2]][joker][player] = ans;
				}
			}
			else {
				ld ans=0;
				int drawn_player=(player+2)%3;
				if (player == 0) {
					ans+=v[1]*solve(v[0]+1,v[1]-1,v[2],joker,n_player);
					ans+=v[2]*solve(v[0],v[1],v[2]-1,joker,n_player);
					ans+=(joker==2)*solve(v[0],v[1],v[2],0,n_player);

					assert(v[1]+v[2]+(joker==2)>=1);
					ans/=v[1]+v[2]+(joker==2);
				}
				else if (player == 1) {
					ans+=v[2]*solve(v[0],v[1]+1,v[2]-1,joker,n_player);
					ans+=v[0]*solve(v[0]-1,v[1],v[2],joker,n_player);
					ans+=(joker==0)*solve(v[0],v[1],v[2],1,n_player);

					assert(v[2]+v[0]+(joker==0)>=1);
					ans/=v[2]+v[0]+(joker==0);
				}
				else if (player == 2) {
					if (v[1]) {
						ans=solve(v[0],v[1]-1,v[2],joker,n_player);
					}
					else if (v[0]) {
						ans=solve(v[0]-1,v[1],v[2]+1,joker,n_player);
					}
					else {
						ans=solve(v,player,n_player);
					}
				}
				memo[v[0]][v[1]][v[2]][joker][player] = ans;
			}
		}
	}
	return memo[v[0]][v[1]][v[2]][joker][player];
}

ld solve(int a, int b, int c, int d, int e) {
	return solve(vector<int>{a, b, c},d,e);
}

int main()
{

	int AB=0,BC=0,CA=0;
	int joker=-1;

	for (int i = 0; i < 101; ++i) {
		for (int j = 0; j < 101; ++j) {
			for (int k = 0; k < 101; ++k) {
				for (int l = 0; l < 3; ++l) {
					for (int m = 0; m < 3; ++m) {
						memo[i][j][k][l][m]=-1;
					}
				}
			}
		}
	}
	{
		int N; cin >> N;

		vector<vector<int>>nums(3, vector<int>(101));
		for (int i = 0; i < 3; ++i) {
			int m; cin >> m;
			map<int, int>mp;
			while (m--) {
				int a; cin >> a;
				mp[a]++;
			}
			for (auto m : mp) {
				if (m.second % 2)nums[i][m.first]++;
			}
		}

		for (int i = 0; i <= N; ++i) {
			if (i == 0) {
				for (int j = 0; j < 3; ++j) {
					if (nums[j][i]) {
						joker=j;
					}
				}
			}
			else {
				if (nums[0][i] && nums[1][i]) {
					AB++;
				}
				else if (nums[1][i] && nums[2][i]) {
					BC++;
				}
				else if (nums[2][i] && nums[0][i]) {
					CA++;
				}
			}
		}
	}

	ld ans=solve(AB,BC,CA,joker,0);

	cout<<setprecision(10)<<fixed<<ans<<endl;
	
	return 0;
}
accuracy: 0.11904761904761904
time_ms: 50
memory_kb: 148168
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repl(i,0,n)
#define mp(a,b) make_pair((a),(b))
#define pb(a) push_back((a))
#define all(x) (x).begin(),(x).end()
#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__",", __VA_ARGS__)
void _dbg(string){cout<<endl;}
template<class H,class... T> void _dbg(string s,H h,T... t){int l=s.find(',');cout<<s.substr(0,l)<<" = "<<h<<", ";_dbg(s.substr(l+1),t...);}
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

#define INF 1120000000

map<int, double> memo;

double solve(int x, int y, int z, int turn, int joker){
  int idx = (((x*100+y)*100+z)*3+turn)*3+joker;
  if(memo.count(idx)==1) return memo[idx];
//  dbg(x,y,z,turn,joker);
  if(x+y+z==0){
    if(joker==1) return 0;
    else return 1;
  }
  double ans=0;
  if(turn==0){
    double total = x+z+(joker==2);
    if(total==0){
      if(y==0){
        if(joker==0) ans = 1;
        else ans = 0;
      }
      else ans = solve(0,y-1,0,1,joker);
    }
    else {
      if(x>0) ans += x*solve(x-1, y, z, 1, joker);
      if(z>0) ans += z*solve(x, y+1, z-1, 1, joker);
      if(joker==2) ans += solve(x,y,z,1,0);
      ans /= total;
    }
  }
  else if(turn==1){
    double total = x+y+(joker==0);
    if(total==0){
      if(z==0){
        if(joker==1) ans=0;
        else ans=1;
      }
      else {
        if(joker==1) ans = solve(0,0,z-1,2,joker);
        else ans = (solve(0,0,z,2,1) + z*solve(0,0,z-1,2,2)) / (z+1.0);
      }
    }
    else {
      if(x>0) ans += x*solve(x-1,y,z+1,2,joker);
      if(y>0) ans += y*solve(x,y-1,z,2,joker);
      if(joker==0) ans += solve(x,y,z,2,1);
      ans /= total;
    }
  }
  else if(turn==2){
    if(y+z+(joker==1) == 0) ans = 1;
    else if(z>0) ans = solve(x,y,z-1,0,joker);
    else if(y>0) ans = solve(x+1,y-1,z,0,joker);
    else if(joker==1) ans = solve(x,y,z,0,2);
  }
//  else assert(false);
  return memo[idx]=ans;
}

int main(){
  int n;
  cin>>n;
  vector<int> vec(n,0);
  int joker=-1;
  rep(i,3){
    int m; cin>>m;
    rep(j,m){
      int d; cin>>d;
      if(d==0) joker=i;
      else {
        d--;
        vec[d] ^= (1<<i);
      }
    }
  }
//  assert(joker!=-1);

  int x=0,y=0,z=0;
  rep(i,n){
    if(vec[i]==5) x++;
    else if(vec[i]==3) y++;
    else if(vec[i]==6) z++;
//    else if(vec[i]!=0) assert(false);
  }

  printf("%.8f\n", solve(x,y,z,0,joker));

  return 0;
}
accuracy: 0.09523809523809523
time_ms: 10
memory_kb: 19252
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repl(i,0,n)
#define mp(a,b) make_pair((a),(b))
#define pb(a) push_back((a))
#define all(x) (x).begin(),(x).end()
#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__",", __VA_ARGS__)
void _dbg(string){cout<<endl;}
template<class H,class... T> void _dbg(string s,H h,T... t){int l=s.find(',');cout<<s.substr(0,l)<<" = "<<h<<", ";_dbg(s.substr(l+1),t...);}
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

#define INF 1120000000

map<int, double> memo;

double solve(int x, int y, int z, int turn, int joker){
  int idx = (((x*100+y)*100+z)*3+turn)*3+joker;
  if(memo.count(idx)==1) return memo[idx];
//  dbg(x,y,z,turn,joker);
  if(x+y+z==0){
    if(joker==1) return 0;
    else return 1;
  }
  double ans=0;
  if(turn==0){
    double total = x+z+(joker==2);
    if(total==0){
      if(y==0){
        if(joker==0) ans = 1;
        else ans = 0;
      }
      else ans = solve(0,y-1,0,1,joker);
    }
    else {
      if(x>0) ans += x*solve(x-1, y, z, 1, joker);
      if(z>0) ans += z*solve(x, y+1, z-1, 1, joker);
      if(joker==2) ans += solve(x,y,z,1,0);
      ans /= total;
    }
  }
  else if(turn==1){
    double total = x+y+(joker==0);
    if(total==0){
      if(z==0){
        if(joker==1) ans=0;
        else ans=1;
      }
      else {
        if(joker==1) ans = solve(0,0,z-1,2,joker);
        else ans = (solve(0,0,z,2,1) + z*solve(0,0,z-1,2,2)) / (z+1.0);
      }
    }
    else {
      if(x>0) ans += x*solve(x-1,y,z+1,2,joker);
      if(y>0) ans += y*solve(x,y-1,z,2,joker);
      if(joker==0) ans += solve(x,y,z,2,1);
      ans /= total;
    }
  }
  else if(turn==2){
    if(y+z+(joker==1) == 0) ans = 1;
    else if(z>0) ans = solve(x,y,z-1,0,joker);
    else if(y>0) ans = solve(x+1,y-1,z,0,joker);
    else if(joker==1) ans = solve(x,y,z,0,2);
  }
  else assert(false);
  return memo[idx]=ans;
}

int main(){
  int n;
  cin>>n;
  vector<int> vec(n,0);
  int joker=-1;
  rep(i,3){
    int m; cin>>m;
    rep(j,m){
      int d; cin>>d;
      if(d==0) joker=i;
      else {
        d--;
        vec[d] ^= (1<<i);
      }
    }
  }
  assert(joker!=-1);

  int x=0,y=0,z=0;
  rep(i,n){
    if(vec[i]==5) x++;
    else if(vec[i]==3) y++;
    else if(vec[i]==6) z++;
    else if(vec[i]!=0) assert(false);
  }

  printf("%.8f\n", solve(x,y,z,0,joker));

  return 0;
}
accuracy: 0.09523809523809523
time_ms: 10
memory_kb: 19280
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef double D;

vector<int> hand(int n){
  vector<int> h(n+1,0);

  int m; cin >> m;
  for(int i=0;i<m;i++){
    int a; cin >> a; h[a]++;
  }
  
  for(int i=0;i<=n;i++) h[i] %= 2;

  return h;
}

D memo2[3][3][110]; //memo2[turn][joker][card]

//0: kotori, 1: umi
D rec2(int t, int j, int c){
  D &res = memo2[t][j][c];
  if(res >= 0) return res;
  
  if(c == 0){
    if(j == 1) return res = 0; //umi loses
    else return res = 1;       //umi wins
  }

  if(t == 0){ //kotori turn
    return res = rec2(1-t,j,c-1);
  }else{     //umi turn
    int total = c + (j==0);
    res = c * rec2(1-t,j,c-1);
    if(j==0) res += rec2(1-t,1,c);
    res /= total;

    return res;
  }
}

D memo3[3][3][110][110][110]; //memo3[turn][joker][hono][umi][koto]

//honoka: 0, umi: 1, kotori: 2
D rec3(int t, int j, vector<int> p){
  D &res = memo3[t][j][p[0]][p[1]][p[2]];
  if(res >= 0) return res;

  //only joker
  if(p[0]==0 && p[1]==0 && p[2]==0){
    if(j == 1) return res = 0; //umi loses
    else return res = 1;       //umi wins
  }

  int nt = (t+1)%3;
  //turn player has no card
  if(j!=t && p[(t+1)%3]==0 && p[(t+2)%3]==0){
    return res = rec3(nt, j, p); //skip turn
  }

  //two players remain
  for(int i=0;i<3;i++){
    if(j!=i && p[(i+1)%3]==0 && p[(i+2)%3]==0){
      if(i==1) return res = 1;                //umi wins
      else return res = rec2(t==1,j==1,p[i]); //umi remains
    }
  }

  //three players remain
  if(t==2){
    if(p[0]){ //umi has cards that kotori also has
      res = rec3(nt, j, {p[0]-1,p[1],p[2]});
    }else if(p[0]==0 && p[2]==0 && j==1){ //umi only has joker
      res = 1;
    }else{
      res = rec3(nt, j, {p[0],p[1]+1,p[2]-1});
    }
  }else{
    int total = p[t] + p[(t+1)%3] + (j==(t+2)%3);

    vector<int> np = p;
    np[t]--;
    np[(t+2)%3]++;
    res = p[t] * rec3(nt,j,np);
    
    np = p;
    np[(t+1)%3]--;
    res += p[(t+1)%3] * rec3(nt,j,np);

    if(j==(t+2)%3) res += rec3(nt,t,p);

    res /= total;
  }
  
  return res;
}

int main(){
  int n;
  cin >> n;

  vector<int> hono = hand(n), umi = hand(n), koto = hand(n);

  int joker = 0;
  if(hono[0] == 1) joker = 0;
  if( umi[0] == 1) joker = 1;
  if(koto[0] == 1) joker = 2;

  int h=0, u=0, k=0;
  for(int i=1;i<=n;i++){
    if(umi[i]  && koto[i]) h++;
    if(koto[i] && hono[i]) u++;
    if(hono[i] &&  umi[i]) k++;
  }

  for(int a=0;a<3;a++){
    for(int b=0;b<3;b++){
      for(int c=0;c<=n;c++){
	memo2[a][b][c] = -1;

	for(int d=0;d<=n;d++){
	  for(int e=0;e<=n;e++) memo3[a][b][c][d][e] = -1;
	}
      }
    }
  }

  cout << fixed << setprecision(10) << rec3(0, joker, {h,u,k}) << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 85784
final_rank: 3