题意:给定一个数组a_1, a_2, .....a_n;且任一项都在[1, m]区间内,要求构造一个数组b,使得对于任意i有gcd(b_1, b_2,.....b_i) = a[i]成立;且任意b_i也在[1, m]区间内。
思路:gcd(b_1, b_2,.....b_i) = a[i] 转化为gcd(a[i-1], b[i]) = a[i]. 可以看出a[i-1]一定要整除a[i],否则无解,在得到即问题转换为在1到
中找到与
互质的数字个数。
#include <bits/stdc++.h>
#pragma GCC optimize (2)
#define oo 0x3f3f3f3f
#define ll long long
#define OO 0x3f3f3f3f3f3f3f3f
#define IO ios::sync_with_stdio(false);cin.tie(nullptr)
#define rep(i,a,n) for (ll i=a;i<=n;i++)
#define per(i,a,n) for (ll i=a;i>=n;i--)
#define int ll
const int N = 2e5 + 10, M = 2 * N;
using namespace std;
typedef pair<int, int> pii;
#define deb(i,x) if(int i==x) int k = 1;
#define all(x) x.begin(),x.end()
ll lowbit(ll x) { return x & -x; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll qmi(ll a, ll b, ll mod) {
ll res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; }
return res;
}
const int mod = 998244353;
signed main()
{
IO;
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t; cin >> t;
while (t--)
{
int n, m; cin >> n >> m;
vector<int>a(n);
for (int i = 0; i < n; i++)cin >> a[i];
bool f = true;
int ans = 1;
for (int i = 1; i < n; i++)
{
if (a[i - 1] % a[i] != 0)
{
f = false;
break;
}
else
{
int d = a[i - 1] / a[i];
vector<int> p;
int temp = d;
for (int i = 2; i <= temp / i; i++)
{
if (temp % i == 0)
{
p.push_back(i);
while (temp % i == 0)temp /= i;
}
}
if (temp > 1)p.push_back(temp);
int sz = p.size();
auto cal = [&](int x)->int
{
int num = 0;
for (int i = 0; i < 1ll << sz; i++)
{
int k = 1;
int cnt = 0;
for (int j = 0; j < sz; j++)
if (i >> j & 1) k *= p[j], cnt++;
if (cnt & 1)
num -= x / k;
else
num += x / k;
}
return num;
};
ans = (ans * cal(m / a[i])) % mod;
}
}
if (f)
cout << ans << endl;
else
cout << 0 << endl;
}
return 0;
}