GCD and LCM
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 188 Accepted Submission(s): 94
Problem Description
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.
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.
Input
First line comes an integer T (T <= 12), telling the number of test cases.
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.
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.
Output
For each test case, print one line with the number of solutions satisfying the conditions above.
Sample Input
2 6 72 7 33
Sample Output
72 0
Source
题目大意:
找出三个数,他们的gcd是g他们的lcm是l。问你有多少组这样的数字。
解题思路:
如果想到把两个数分解成素数,会很简单。g分解成a1^n1*a2^n2*a3^n3...l也分解成b1^m1*b2^m2...
会发现l的因子必须把g的因子含进去,不光是类别而且是每个类的数目。我们可以直接判别l%g!=0的话就直接输出0. l%g==0的话l=l/g。然后只需要对l分解成素数即可。l=b1^m1*b2^m2...假设三个数满足题目的条件则有lcm(q1,q2,q3)=l gcd(q1,q2,q3)=1,设这三个数为q1,q2,q3,q1=b1^s1*q2^s4...,q2=b1^s2*q2^s5...,q3=b1^s3*q2^s6.
由于lcm(q1,q2,q3)=l gcd(q1,q2,q3)=1 所以min(s1,s2,s3)=0,max(s1,s2,s3)=m1.s1取0,s2取m1,s3取1~m1,这样的共有(m1-1)*6,6是排列数。s1,s2取0,s3取m1的共有3。 s1,s2取m1,s3取0的也有3种。 以上三种情况里的s1,s2,s3顺序可以排列,所以已经乘上了组合数。三者相加便是6*m1。然后依次其它计算方式一样然后答案就是6*m1*6*m2*6*m3.....详见代码。(开始准备素数打表,T总共才12无需打标)
题目地址:GCD and LCM
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int isprim(int x) //判定是素数
{
int flag=1,i;
for(i=2;i<=sqrt(x+0.5);i++)
if(x%i==0)
{
flag=0;
break;
}
return flag;
}
int main()
{
int tes,g,l,i;
scanf("%d",&tes);
while(tes--)
{
scanf("%d%d",&g,&l);
if(l%g!=0) puts("0");
else
{
l=l/g;
__int64 sum;
sum=1;
for(i=2;i<=sqrt(l+0.5);i++)
if(isprim(i)&&(l%i==0))
{
int p=0;
while(l%i==0)
{
l/=i;
p++;
}
sum=sum*6*p; //刚推的式子
}
if(l>1) sum*=6; //比如说9999997这样的数
printf("%I64d\n",sum);
}
}
return 0;
}