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

思路:

设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; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值