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;
}