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

xiaoxiao2021-02-28  116

思路:

设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; }
转载请注明原文地址: https://www.6miu.com/read-19937.html

最新回复(0)