Description
YMW最近迷上了数学,听BPM说,善于思考的孩纸才是好孩纸呢,于是他一边看书,一边开始思考些问题。他看到书上说枚举是最强大的算法,他很不服气,思考片刻,便想出一道题,如果我们有两个正整数a,b,那会有多少对数,满足他们之间的最大公因数是a,最小公倍数是b呢?而你是暴力的最忠实粉丝,你能用枚举进行解决吗?
Input
多组数据,每组数据只有一行,每行两个正整数a,b
以输入文件结束结尾
Output
每组数据输出一个整数,表示符合的有多少对,每组数据占一行
Hint
样例解释,第一组存在4对(3,60),(12,15),(15,12),(60,3),第二组只有(2,2)
数据范围:
不超过100组数据
对于30%的数据2<=a<=2000,2<=b<=2000
对于70%的数据2<=a<=20 0000,2<=b<=20 0000
对于100%的数据2<=a<=20 0000 0000,2<=b<=20 0000 0000
Source
BY BPM
Solution
水题
已知a*b/gcd(a,b)=lcm(a,b),变形得lcm(a,b)*gcd(a,b)=a*b
对于给定的每个gcd和lcm,我们求积并枚举其中一个a,找另一个b
显然这样做还是会T的。不难发现a=gcd(a,b)*k,b=gcd(a,b)*l这样a、b均为gcd的倍数,那么我们枚举gcd前的倍数就可以了
Code
#include <stdio.h>
#include <math.h>
#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)
#define max(x, y) (x)>(y)?(x):(y)
#define ll long long
inline int gcd(int x, int y){return !y?x:gcd(y,x % y);}
int main(void){
int n, m;
while (scanf("%d %d", &n, &m) != EOF){
if (n == m){
puts("1");
continue;
}
ll lim =(ll)(n) * (ll)(m);
int ans = 0;
rep(i, 1, sqrt(lim) / n){
int x = n * i;
int y = lim / x;
ans += (!(lim % x) && gcd(x, y) == n);
}
printf("%d\n", ans * 2);
}
return 0;
}