洛谷 1029 最大公约数和最小公倍数问题

来源:互联网 发布:淘宝内部优惠卷软件 编辑:程序博客网 时间:2024/06/05 20:51

思路:

设x,y,设l=lcm=最小公倍数,g=gcd=最大公约数。

则有:

x=a1^z1*a2^z2*…an^zn;//x的质因数分解 ,例如:30=2^1*3^1*5^1;

y=a1^q1*a2^q2*…an^qn;//y的质因数分解 , 例如:40=2^3*3^0*5^1;

因此:

l=a1^max(z1,q1)a2^max(z2,q2)…an^max(zn,qn);//l即取每个质因数的最多次数,例如:l(30,40)=2^3*3^1*5^1=120;

g=a1^min(z1,q1)a2^min(z2,q2)…an^min(zn,qn);//g即取每个质因数的最少次数, 例如:g(30,40)=2^1*3^0*5^1=10;

对于可能的x,y每个指数都有2种情况,即max 或 min;所以总情况数sum应该是2^n;

但是如果zi=qi呢?

设 k=l/g;//设k=l/g,例如k(120,10)=12

k=b1^d1*b2^d2*…bw^dw;//k的质因数分解 ,目的是为了去掉l,g重复的部分, 例如:12=2^2*3^1*5^0;

sum=2^w;//每个d1都有2种情况,即max or min;所以总情况数sum=2^w;

代码://由于担心质因数分解超时,用了欧拉筛素法,不怕死的可以去了试试;

#include<bits/stdc++.h>using namespace std;int f[10000000],a[78498],cnt;int x,y,k,c,sum,b[78498];int main(){    //欧拉筛素法;     for(int i=2;i<=1000000;i++)    {        if(f[i]==0)a[cnt++]=i;        for(int j=1;j<=cnt;j++)        {            if(i*a[j-1]>1000000)break;            f[i*a[j-1]]=1;            if(i%a[j-1]==0)break;        }}//下面是真正代码 ;    scanf("%d%d",&x,&y);    if(y%x!=0){printf("0");return 0;}    k=y/x;    while(k!=1)(k%a[c]!=0)?c++:(k/=a[c])&&(b[c]=1);    for(int j=0;j<=c;j++)if(b[j]==1)sum++;    printf("%d",(1<<sum));    return 0; }