zoukankan      html  css  js  c++  java
  • 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 imes (k-1)+3 imes 2 = 6 imes 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;
    }
    
  • 相关阅读:
    实现Runnable接口和继承Thread类的区别
    图的DFS和BFS
    图建模
    数据结构-图的基本知识和表示
    除自身以外的乘积数组(力扣第238题)
    MapReduce源码分析--Shuffle阶段
    转到博客园
    vue中使用剪切板插件 clipboard.js
    vue中使用vue-qrcode生成二维码
    h5中嵌入视频自动播放的问题
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/13574152.html
Copyright © 2011-2022 走看看