洛谷P1072 Hankson的趣味题
solution:
很妙的数学推导题
易知,一般的,令\(k = \gcd(a, b)\),则\(\gcd(a / k, b / k) = 1\)。
那么将\(\gcd(x, a_0) = a_1\)转化为\(\gcd(x / a_1, a_0 / a_1) = 1\) ①
又由\(b_1 = \operatorname{lcm}(x, b_0) = x * b_0 / \gcd(x, b_0)\)知,
\(\gcd(x, b_0) = x * b_0 / b_1\)。令\(k_1 = \gcd(x, b_0)\),
则\(\gcd(x / k_1, b_0 / k_1) = 1\)
化简得\(\gcd(b_1 / b_0, b_1 / x) = 1\) ---------------------------------②
由①②式的限制,可以设计出算法:
枚举\(b_1\)的因数\(i\),判断\(i\)是否是\(a_1\)的倍数,并且是否满足①②式子。
若满足则\(i\)是符合题目要求的数之一。
时间复杂度O(\(\sqrt{b_1}\))。
code:
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
int T;
LL a_0, a_1, b_0, b_1;
LL GCD(LL A, LL B) {
if(!B) return A;
return GCD(B, A % B);
}
int main() {
#ifdef test
freopen("test.txt", "r", stdin);
#endif
cin >> T;
int ans = 0;
while(T--) {
ans = 0;
cin >> a_0 >> a_1 >> b_0 >> b_1;
for(int i = 1; i * i <= b_1; i++) { // 因子i
if(b_1 % i) continue;
if(i % a_1 == 0 && GCD(i / a_1, a_0 / a_1) == 1 && GCD(b_1 / b_0, b_1 / i) == 1)
ans++;
int h = b_1 / i; // 大于根号N的因子。
if(h == i) continue; // 特判当i等于h的情况,此时两个因子重复不能计入答案。
if(h % a_1 == 0 && GCD(h / a_1, a_0 / a_1) == 1 && GCD(b_1 / b_0, b_1 / h) == 1)
ans++;
}
cout << ans << endl;
}
return 0;
}