Given two positive integers G and L, could you tell me how many solutions of (x, y, z) there are, satisfying that gcd(x, y, z) = G and lcm(x, y, z) = L?
Note, gcd(x, y, z) means the greatest common divisor of x, y and z, while lcm(x, y, z) means the least common multiple of x, y and z.
Note 2, (1, 2, 3) and (1, 3, 2) are two different solutions.
InputFirst line comes an integer T (T <= 12), telling the number of test cases.
Note, gcd(x, y, z) means the greatest common divisor of x, y and z, while lcm(x, y, z) means the least common multiple of x, y and z.
Note 2, (1, 2, 3) and (1, 3, 2) are two different solutions.
The next T lines, each contains two positive 32-bit signed integers, G and L.
It’s guaranteed that each answer will fit in a 32-bit signed integer.OutputFor each test case, print one line with the number of solutions satisfying the conditions above.Sample Input
2 6 72 7 33Sample Output
72 0
题意:给你 一个最大公约数和一个最小公倍数,让你求满足这样的三元组有多少个;
当时做这道题时,一头扎进了当 最小公倍数 l,和 最大公约数 g 找出 满足 乘积 为 l/g的 三个数且这三个数互质(最大公约为1),还把 l/g 分解成素数相乘,真是,怎么也找不出来;这道题考的是最大公约数 和最小公倍数的 本质;
首先我们可以写出GCD(x,y,z)和LCM(x,y,z)的公式
我们知道任意一个数x可以拆分成x=p1^e1*p2^e2...pk^ek(pi是因质数)
而且GCD(x,y,z)=p1^(min(xe1,ye1,ze1))*p2^(min(xe2,ye2,ze2))...pk^(min(xek,yek,zek))
LCM(x,y,z)=p1^(max(xe1,ye1,ze1))*p2^(max(xe2,ye2,ze2))...pk^(max(xek,yek,zek))
在x,y,z这三个数化为分解素数的乘积时,所有个对于 p ,x ,y,z中,一定有一个 取最大max,一定有一个取最小,另一个就随意取了[min,max],
当 这个随意取,取(min,max),时,这三个数都不一样,所以由 6中排序当时,因为取的是(min,max),所以6 *(max-min-1);
当 取min时,这三个数中有两个一样的,所以 只有3种排列方式;
当 取max时,同上,有两个一样的,有3中排列方式;
所以由对于每个p,有 6*(max-min-1)+ 3+3 = 6 *(max-min)种;
让这个所有的相乘就是全部的;
max-min 其实是,l/g 化成 素数相乘的 素数的指数;
所以代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define ll long long #define Max 200005 ll prime[Max]; bool is_prime[Max]; ll sum[Max]; ll tt[Max]; ll num; ll cot; void init() { num = 0; memset(is_prime,true,sizeof(is_prime)); is_prime[0] = false; is_prime[1] = false; ll i,j; for(i = 2;i<Max;i++) { if(is_prime[i]) { prime[num++] = i; for(j = 2;j*i<Max;j++) is_prime[j*i] = false; } } } void find(long long x) { ll i,j; cot = 0; for(i = 0;i<num;i++) { ll pp = 0; if(x%prime[i]==0) while(x%prime[i]==0) { x /= prime[i]; pp++; } sum[cot++] = pp; } } if(x!=1) sum[cot++] = 1; } int main() { ll i,j,t; init(); scanf("%lld",&t); ll g,l; while(t--) { scanf("%lld%lld",&g,&l); if(l%g) printf("0\n"); else { l /= g; find(l); ll res = 1; for(i = 0;i< cot;i++) res *=6*sum[i]; printf("%lld\n",res); } } return 0; }