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 C++ (judge verdict: Wrong Answer)

#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
/*
long long int gcd(long long int x, long long int y){
  if(x < y) swap(x,y);
  while(y){
    x %= y;
    swap(x,y);
  }
  return x;
}
*/
int main(){
  long long int n, m;
  cin >> n >> m;
  vector<long long int> A(n);
  vector<int> P(n);
  for(int i = 0; i < n; ++i) cin >> A[i];
  for(int i = 0; i < n; ++i) cin >> P[i];
  double ans = 0;
  vector<long long int> LCM;
  vector<double> P_;
  vector<int> C;
  LCM.push_back(1);
  P_.push_back(1.0);
  C.push_back(0);
  for(int i = 0; i < n; ++i){
    long long int s = LCM.size();
    for(long long int j = 0; j < s; ++j){
      long long int t = LCM[j]/__gcd(LCM[j],A[i])*A[i];
      if(t > m) continue;
      double p = P_[j]*P[i]/100.0;
      int c = C[j] + 1;
      if(c%2) ans += m/t*p;
      else ans -= m/t*p;
      LCM.push_back(t);
      P_.push_back(p);
      C.push_back(c);
      //cout << t << " " << p << " " << c << endl;
    }
  }
  printf("%.12f\n",ans);
  return 0;
}