原题面:https://www.acwing.com/problem/content/202/
题目大意:gcd(x,a0)=a1,lcm(x,b0)=b1,问你有多少满足条件的正整数x。
输入描述:t组输入,第一行一个整数t,代表测试数据的组数。接下来t行,每行四个整数,a0,a1,b0,b1。
输出描述:对于每组测试数据,输出满足条件的x的个数。
输入样例:
2 41 1 96 288 95 1 37 1776
输出样例:
6 2
分析:lcm(x,b0)=b1说明x一定是b1的因子,可以预处理跑出1e5范围内的质数,再对b1进行质因子分解,最后dfs枚举b1的因子,去检测是否满足gcd(x,a0)=a1&&lcm(x,b0)=b1,如果满足且不重复,则使答案加一。
代码:
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+7; typedef long long ll; int n;ll a,b,c,d; map<ll,int> vis; int v[maxn];ll prime[maxn];int cnt,ans; vector<ll> divisor; ll gcd(ll a,ll b) { return !b ? a : gcd(b, a % b); } ll lcm(ll a,ll b) { return a * b / gcd(a, b); } void sieve() { cnt = 0; memset(v, 0, sizeof(v)); for (int i = 2; i < maxn; i++) { if (!v[i]) { v[i] = i; prime[cnt++] = i; } for (int j = 0; j < cnt; j++) { if (v[i] < prime[j] || i * prime[j] >= maxn) break; v[i * prime[j]] = prime[j]; } } } void depart(ll d) { divisor.clear(); for (int i = 0; prime[i] * prime[i] <= d; i++) { while (d % prime[i] == 0) { divisor.push_back(prime[i]); d /= prime[i]; } } if (d > 1) divisor.push_back(d); } void dfs(ll x,int p,int n) { if (p == n) { //cout<<x<<endl; if (vis[x]) return; vis[x] = 1; if (gcd(a, x) == c && lcm(b, x) == d) ans++; return; } dfs(x * divisor[p], p + 1, n); dfs(x, p + 1, n); } //gcd(x,a0)=a1 lcm(x,b0)=b1 int main() { sieve(); cin >> n; while (n--) { ans = 0; vis.clear(); cin >> a >> c >> b >> d; depart(d); dfs(1, 0, divisor.size()); cout << ans << endl; } return 0; }