1. 程式人生 > 實用技巧 >洛谷 P1072 【Hankson 的趣味題】

洛谷 P1072 【Hankson 的趣味題】


這題看起來很難其實很簡單,只需要暴力就能算出來,複雜度$O(n$ $√b1$ $log(√b1))$,能跑過去。

由題意得:

$gcd(x, a0) = a1$;

$lcm(x, b0) = b1$;

這就說明$x$是$a1$的整數倍,且$x$是$b1$的因子。

那麼我們只需要列舉$b1$的因子然後判斷是否是$a1$的整數倍且滿足上面的一個$gcd$和一個$lcm$。

但因為列舉$b1$的因子複雜度太高,所以可以列舉到 $√b1$ 然後通過$b1$除以這個因子得到另一個因子。

但注意當$x * x = b$1時,兩個因子的答案加一次就行了。

$code:$

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 #define ll long long
 4 using namespace std;
 5 int T, a0, a1, b0, b1;
 6 int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}
 7 ll lcm(int a, int b) {return 1ll * a * b / gcd(a, b);}
 8 int main()
9 { 10 scanf("%d", &T); 11 while(T--) 12 { 13 int ans = 0; 14 scanf("%d %d %d %d", &a0, &a1, &b0, &b1); 15 for(int i = 1; i * i <= b1; ++i) 16 { 17 if(b1 % i != 0) continue; 18 if(i % a1 == 0 && gcd(i, a0) == a1 && lcm(i, b0) == 1ll * b1) ++ans;
19 if(i * i == b1) continue; 20 int j = b1 / i; 21 if(j % a1 == 0 && gcd(j, a0) == a1 && lcm(j, b0) == 1ll * b1) ++ans; 22 } 23 printf("%d\n", ans); 24 } 25 return 0; 26 }