最大公约数和最小公倍数问题

题目背景
NOIP2001 普及组
题目描述
输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数
条件:  
1.P,A是正整数
2.要求P,Q以x0为最大公约数,以y0为最小公倍数.
试求:满足条件的所有可能的两个正整数的个数.

为了响应勤俭节约的号召,我就不描述题目了。

这是一道很简单的题,没错。然而在我研究gcd和lcm之前,是完全不会。。。好吧好吧,现在研究会了就行了。
这道题就是,如果暴力求解,就会TLE
首先要知道公式lcm(a,b)=a*b/gcd(a,b),(具体到下方讨论)然后就可以根据一个值求另一个了。只需要枚举i,不需要枚举j。然而还可以再优化,也就是,i一定是gcd的倍数,i可以一次性加上gcd。加完之后,需要判断是否可以使用这个i。可以的话就让tot+1

#include  
using namespace std;  
inline int gcd(int a,int b){     //求gcd的算法。inline是用来加速的
    if(b==0)return a;  
    return gcd(b,a%b);  
}  
int main(){  
    int n,m,tot=0;  
    cin>>n>>m;                  //m是lcm,n是gcd
    for(int i=n;i<=m;i+=n){     //枚举i
        if(m%i==0){             //如果lcm根本就不是i的倍数,也就不用求了
            int j=(n*m)/i;      //根据上面那个公式推出的求j公式
            if(gcd(i,j)==n)tot++;  //即使有j,i和j也不一定会gcd给出的m
        }  
    }  
    cout<

而lcm(a,b)=a*b/gcd(a,b)呢,就需要以下证明
a的质因数集:{a0,a1……an}
b的质因数集:{b0,b1……bn}
存在am1=bn1,am2=bn2……
所以gcd(a,b)=am1*am2……
lcm(a,b)=a*b/(am1……)出去两个集合相同的元素,也就是gcd(a,b)

你可能感兴趣的:(最大公约数和最小公倍数问题)