HDU 4497 GCD and LCM(数论+组合数学)

题目链接

题目大意

  给出g,l,求有多少对a,b,c满足gcd(a,b,c)=g,lcm(a,b,c)=l,不同的数之间顺序不同也算不同的对。

解题思路

  首先肯定只有\(g|l\)的情况下才有解。从lcm下手,因为三个数的gcd是一样的,所以lcm先除去gcd,然后对l/g分解质因数。
  设其中一个质因数为p,指数为k,显然,三个数中必定有一个是\(p^k\),一个是\(p^0\),不然就和gcd与lcm的定义违背了,而第三个数可以是0~k,一共有k+1中选法,然后因为有次序关系,不同的次序结果也不同。
  如果第三个数与前两个数都不同,那么一共有6种选法,如果有一个相同,那么有3种选法,结果就是\(6\times (k-1)+3\times 2 = 6\times k\)种选法。由乘法原理可得,最后的结果就是l/g的每个质因子的指数的6倍相乘。

代码

const int maxn = 1e5+10;
const int maxm = 2e2+10;
int p[maxn], u[maxn];
int main() {
    for (int i = 2; i<maxn; ++i) {
        if (!u[i]) u[i] = p[++p[0]] = i;
        for (int j = 1; i*p[j]<maxn; ++j) {
            u[i*p[j]] = p[j];
            if (i%p[j]==0) break;
        }
    }
    int t; cin >> t;
    while(t--) {
        ll g, l; cin >> g >> l;
        if (l%g) cout << 0 << endl;
        else {
            ll ans = 1; l /= g;
            for (int i = 1; (ll)p[i]*p[i]<=l; ++i)
                if (l%p[i]==0) {
                    int cnt = 0;
                    while(l%p[i]==0) l /= p[i], ++cnt;
                    ans *= 6LL*cnt;
                }
            if (l>1) ans *= 6LL;
            cout << ans << endl;
        }
    }
    return 0;
}
posted @ 2020-08-27 21:38  shuitiangong  阅读(141)  评论(0编辑  收藏  举报