Problem:
Enumeration

n個の整数a1, a2, …, anとn個の整数p1, p2, …, pn、整数mが与えられる。k番目の整数akをpk[%]の確率で選ぶ、という操作を各k(1 ≤ k ≤ n)について行い、0個以上n個以下の整数を選び出す。1以上m以下の整数の中で、選ばれた整数の少なくとも1つで割り切れるものの個数の期待値を求めよ。

Input

入力は以下の形式で与えられる。

n m
a1 a2 … an
p1 p2 … pn

Constraints

1 ≤ n ≤ 20

1 ≤ m ≤ 1018

1 ≤ ak ≤ 1018 (1 ≤ k ≤ n)

1 ≤ pk ≤ 99 (1 ≤ k ≤ n)

Output

問題の解を1行に出力せよ。出力には絶対誤差あるいは相対誤差で0.0000001(= 10-7)を超える誤差があってはならない。

Sample Input 1

2 15
3 5
50 50

Output for the Sample Input 1

3.75

確率

選ばれた数字

割り切る数

個数

25%

[]

 

0個

25%

[3]

3 6 9 12 15

5個

25%

[5]

5 10 15

3個

25%

[3,5]

3 5 6 9 10 12 15

7個

よって0.25 × (0 + 5 + 3 + 7) = 3.75

Sample Input 2

4 100
2 3 5 7
80 60 40 20

Output for the Sample Input 2

57.352

Sample Input 3

4 210
2 3 5 7
80 60 40 20

Output for the Sample Input 3

119.9136

Solution in JAVA (judge verdict: Accepted)

import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Scanner;

public class Main{
	public static void main(String[] args) {
		new Main().run();
	}

	void run() {
		solver();
	}

	void solver() {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		long m = sc.nextLong();

		long[] a = new long[n];
		for (int i = 0; i < n; i++)
			a[i] = sc.nextLong();
		MathContext mc = new MathContext(25, RoundingMode.HALF_EVEN);

		// BigDecimal[] p = new BigDecimal[n];
		// for (int i = 0; i < n; i++)
		// p[i] = (new BigDecimal(sc.nextInt())).divide(BigDecimal.valueOf(100),
		// mc);
		int[] p = new int[n];
		for (int i = 0; i < n; i++)
			p[i] = sc.nextInt();

		long[] cnt = new long[1 << n];
		for (int i = 1; i < (1 << n); i++) {
			long l = 1;
			for (int j = 0; j < n; j++) {
				if (((i >> j) & 1) == 1) {
					l = lcm(l, a[j]);
					if (l == 0)
						break;
				}
			}
			if (l != 0)
				cnt[i] += m / l;
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < (1 << n); j++) {
				if (((j >> i) & 1) == 1) {
					cnt[j] -= cnt[j ^ (1 << i)];
				}
			}
		}
		double ans = 0;
		// BigDecimal ans = new BigDecimal(0);
		for (int i = 0; i < (1 << n); i++) {
			// BigDecimal pro = BigDecimal.valueOf(Math.abs(cnt[i]));
			double pro = Math.abs(cnt[i]);
			for (int j = 0; j < n; j++) {
				if (((i >> j) & 1) == 1) {
					// pro = pro.multiply(p[j], mc);
					pro *= p[j] / 100.0;
				} else {
					pro *= (100 - p[j]) / 100.0;
					// pro = pro.multiply(BigDecimal.ONE.subtract(p[j], mc),
					// mc);
				}
			}
			ans += pro;
//			ans = ans.add(pro, mc);

		}
		System.out.printf("%.10f\n", ans);
	}

	long gcd(long a, long b) {
		if (a < b) {
			long tmp = a;
			a = b;
			b = tmp;
		}
		if (b == 0)
			return a;
		else
			return gcd(b, a % b);
	}

	long lcm(long a, long b) {
		a /= gcd(a, b);
		if (a * b / b != a)
			return 0;
		else
			return a * b;
	}

	void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}