P1072. Hankson 的趣味题

考点

  • 最大公约数

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }

int lcm(int a, int b) { return a / gcd(a, b) * b; }

int main() {
int n, a0, a1, b0, b1;
cin >> n;
while (n--) {
cin >> a0 >> a1 >> b0 >> b1;
int ans = 0;
for (int i = 1; i <= b1 / i; ++i) {
if (b1 % i == 0) {
if (gcd(i, a0) == a1 && lcm(i, b0) == b1) ++ans;
if (i != b1 / i && gcd(b1 / i, a0) == a1 && lcm(b1 / i, b0) == b1)
++ans;
}
}
cout << ans << endl;
}
return 0;
}

思路

有两种思路枚举x:

  1. 由于a1是x的约数,可以枚举a1的倍数,直到b1为止

    时间复杂度为\[O\left( \frac{b1}{a1} \right)\]

  2. 由于x是b1的约数,可以枚举b1的约数

    时间复杂度为\[O\left( \sqrt{b1} \right) \]

显然应该选第二种,每次判断ib1/i这一对约数是否满足条件即可