1 条题解

  • 1
    @ 2026-02-10 21:34:09

    前置知识

    最大公约数(即 \(\gcd\)) 和最小公倍数(即 \(\operatorname{lcm}\))的求法。

    该题的关键点在于,两个数的积等于它们最大公约数和它们最小公倍数的积。公式表示为 \(a\times b=\gcd(a,b)\times \operatorname{lcm}(a,b)\)。设作为答案的两个数为 \(x\) 和 \(y\),我们要使它们同时满足以下三个条件,并统计这样的 \(x\) 和 \(y\) 的个数(\(P,Q\) 含义见题目描述):

    1. \(x\times y=P\times Q\)
    2. \(P=\gcd(x,y)\)
    3. \(Q=\operatorname{lcm}(x,y)\)

    我们可以枚举 \(x\),判断是否存在满足条件 \(1\) 的整数 \(y\)(即,\(x\) 能否被 \(P,Q\) 的积整除)。满足第一个条件后,再分别判断当前的 \(x,y\) 是否能够同时满足另外两个条件即可。显然,这种做法会超时。

    考虑优化这个程序。我们其实并不需要枚举两次,因为对于不同的 \(x,y\) ,交换它们的值一定可以得到另一组与之对应的解。因此,从 \(1\) 到 \(P\times Q\) 枚举一遍,每发现一组答案就将 \(ans\) 的值加上 \(2\) 即可。

    一组 \(x,y\) 有对应解时有条件:\(x,y\) 的值不同。如果它们相同,交换后并不能得到与之对应的另一组数。当 \(x=y\) 时,易得 \(x=y=\gcd(x,y)=\operatorname{lcm}(x,y)\)。 所以要对此进行特判,若 \(P,Q\) 相等,这种情况就存在,\(ans\) 里要减去 \(1\)。

    一些代码实现技巧:

    C++ 里有一个自带的求 \(\gcd\) 的函数叫 __gcd 。upd:现在 NOIP 已经可以使用了。

    当积相同且 \(\gcd\) 相同时,\(\operatorname{lcm}\) 也一定相同,因此只需判断是否满足一、二两个条件即可。

    AC 代码:(应该是目前最短的)

    #include<bits/stdc++.h>
    using namespace std;
    long long m,n,ans;
    int main(){
        cin>>m>>n;
        if(m==n) ans--;
        n*=m;//把两数的积存入n中 
        for(long long i=1;i<=sqrt(n);i++){
            if(n%i==0&&__gcd(i,n/i)==m) ans+=2;
        }
        cout<<ans;
        return 0;
    }
    
  • 1

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

信息

ID
1015
难度
6
分类
数学枚举 点击显示
标签
递交数
1
已通过
1
通过率
100%
上传者