题面
题目描述
输入两个正整数 (x_0, y_0),求出满足下列条件的 (P, Q) 的个数:
- (P,Q) 是正整数。
- 要求 (P, Q) 以 (x_0) 为最大公约数,以 (y_0) 为最小公倍数。
试求:满足条件的所有可能的 (P, Q) 的个数。
输入输出格式
输入格式
一行两个正整数 (x_0, y_0)。
输出格式
一行一个数,表示求出满足条件的 (P, Q) 的个数。
输入输出样例
输入样例 #1
3 60
输出样例 #1
4
说明
(P,Q) 有 (4) 种:
- (3, 60)。
- (15, 12)。
- (12, 15)。
- (60, 3)。
对于 (100\%) 的数据,(2 le x_0, y_0 le {10}^5)。
分析
考虑数论做法,废话数论试炼场里面当然是数论了,首先有定理:两个数的乘积等于它们最小公倍数和最大公约数的乘积。也就是:
简证:
首先我们知道,对于任意正整数(a,b),都有
也就是(dfrac{a}{gcd(a,b)},dfrac{b}{gcd(a,b)})互质。原因很简单,如果它们不互质,就肯定有一个更大的公约数。
这个时候就能得到:
说实话,当年我见到这个式子我是完全蒙圈的,光看确实比较难理解。如果你自己在草稿纸上画一画,你就明白了大概了。刚刚说,(dfrac{a}{gcd(a,b)},dfrac{b}{gcd(a,b)})互质,也就是说最大公因数其实有一个显然的特征,两个数除以它们的最大公因数后互质。非常显然,(dfrac{a}{gcd(a,b)} imes b = dfrac{b}{gcd(a,b)} imes a = dfrac{a imes b}{gcd(a,b)})。还是因为(dfrac{a}{gcd(a,b)},dfrac{b}{gcd(a,b)})互质,所以三者不能在不破坏(a,b)的情况下同时做除法。此时(dfrac{a imes b}{gcd(a,b)} = operatorname{lcm}(a,b)),变形就可以得到(a imes b = gcd(a,b) imes operatorname{lcm}(a,b))了。
举个例子吧,(4,6),它们的最大公因数是(2)。此时有(dfrac{4}{2} imes6 = dfrac{6}{2} imes4 = dfrac{4 imes6}{2}),也就是(2 imes6 = 3 imes4 = 12) 。此时不能在不破坏原数(4,6)的情况下同时做除法,所以(4,6)的最小公倍数是(12) 。但别忘了,这个(12)还有(dfrac{4 imes6}{2})的身份。这啥啊,这就是两个数的乘积除以最大公约数。两边同时( imes 2),(12 imes 2 = 4 imes 6)。 完美。
证了这么半天的定理,有啥用吗?当然有了。我们可以考虑一种做法,枚举(i)从(1 sim sqrt{n imes m}),通过(dfrac{n imes m}{i})求出另一个数,再判断这两个数的最大公因数是不是(m)即可,如果是ans++
。轻松愉快兴奋激动。(?
当然了还有一些注意事项:
- 由于我们这里只枚举了(i)到(sqrt{n imes m}),但是题目中两个符合要求的数调换后会得到一个新的答案。所以这里我们最后要
ans *= 2
。当然了,如果你开心,也可以在循环过程中写ans += 2
,也可以达到相同的效果。 - 小心(n = m) 情况。这种情况下会有一种答案,这种答案中的两个数相同,都为(n)。但是这种答案调换两个数后并不会得到一个新的答案,所以我们需要特判:
if(n == m) ans--
。注意这里可别写到ans *= 2
之前,那样就相当于ans -= 2
了。我差点掉进这个坑。
代码
代码实现比较简单。
/*
* @Author: crab-in-the-northeast
* @Date: 2020-02-26 12:49:17
* @Last Modified by: crab-in-the-northeast
* @Last Modified time: 2020-02-26 14:01:06
*/
#include <iostream>
#include <cstdio>
#include <cmath>
long long gcd(int a,int b) {
return a % b ? gcd(b,a % b) : b;
}
int main() {
int m,n;
int ans = 0;
scanf("%d%d",&m,&n);
for(int i = 1; i <= sqrt(m * n);i++)
if(n * m % i == 0 && gcd(i,n * m / i) == m)
ans++;
ans *= 2;
if(n == m) ans--;
printf("%d
",ans);
return 0;
}
评测记录
AC 100
:R31075842