HDU 4497GCD and LCM(素数分解)

来源:互联网 发布:同志漫画软件 编辑:程序博客网 时间:2024/05/01 03:54

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.
 

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.
 

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
2013 ACM-ICPC吉林通化全国邀请赛——题目重现
 

                 题目大意:找出三个数,他们的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;}



原创粉丝点击