🧮

唯一分解定理

每个数都有一张独一无二的"质因子配方"

💡 打个比方

把每个合数都看成一道菜,质数就是食材。唯一分解定理说:每道菜的配方是唯一的——60 只能写成 2×2×3×5,换任何顺序、换任何食材都不行。

有了配方,还能顺便算出"它能切出多少份"(约数个数):每个质因子有"用 0 次、1 次、…、指数次"的选法,把各质因子的选法数相乘,就是约数个数。

唯一分解定理:每个大于 1 的整数都能唯一写成质因子的乘积。60 = 2² × 3¹ × 5¹,约数个数 = (2+1)×(1+1)×(1+1) = 12 个。

🖼️ 大图看明白

① 因子树:60 一层层拆,最后全是质数 60 2 30 2 15 3 5 60 = 2 × 2 × 3 × 5(配方唯一) ② 看配方数约数个数 60 = 2² × 3¹ × 5¹ 各质因子的指数:2、1、1 (2+1) × (1+1) × (1+1) = 12 每个质因子可选"用 0 次 ~ 指数次",选法数相乘 1 2 3 4 5 6 10 12 15 20 30 60 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60 —— 正好 12 个

📏 试除分解,只要 3 步

  1. 第 1 步:从小到大试除。从 2 开始:n 能被 i 整除,就一直除、数次数 e,记下"i 出现 e 次";i 加 1 继续。只需试到 i × i ≤ n。
  2. 第 2 步:处理剩下的。循环结束后如果 n 还大于 1,剩下的这个数本身就是质数(最大的质因子),补记"出现 1 次"。
  3. 第 3 步:配方在手,约数个数直接算。把每个质因子的"指数 + 1"相乘,就是约数个数。
为什么试到 √n 就够?如果 n 还有合数因子,它必然有一个 ≤ 它的平方根的质因子,早就被试掉了。剩下的 > 1 的部分只可能是质数。

💻 C++ 怎么写

// 试除分解 + 数约数个数(以 n = 60 为例)
int main() {
    int n; cin >> n;
    int m = n, divCnt = 1;
    for (int i = 2; i * i <= m; i++) {
        if (m % i == 0) {
            int e = 0;
            while (m % i == 0) { m /= i; e++; }
            cout << i << " 出现 " << e << " 次\n";
            divCnt *= (e + 1);      // 约数个数:指数+1 相乘
        }
    }
    if (m > 1) {                    // 剩下的就是质因子
        cout << m << " 出现 1 次\n";
        divCnt *= 2;
    }
    cout << "约数个数: " << divCnt << endl;  // 12
    return 0;
}
考点提醒:① 循环条件用 i * i <= m,注意 m 在变小,不用试到原数;② m > 1 的剩余因子别忘了补上;③ 求约数个数是 (e+1) 相乘,不是相加。

✋ 你来试试

题 1:36 的质因子配方是什么?它有多少个约数?
36 = 2 × 18 = 2 × 2 × 9 = 2 × 2 × 3 × 3 = 2² × 3²。约数个数 = (2+1) × (2+1) = 9 个:1, 2, 3, 4, 6, 9, 12, 18, 36。可以数一数验证。
题 2:试除分解时,为什么循环只需要跑到 i × i ≤ n?
假设 n = a × b 且 a ≤ b,那么 a 一定 ≤ √n。也就是说小的那个因子一定不超过平方根,循环到 √n 就一定能找到它。如果一路除完还剩一个大于 1 的数,它不可能再分解(否则会有一对因子,其中较小者 ≤ √它,早被试掉了),所以它本身就是质数。
🎯 一句话记住:每个数的质因子配方唯一(唯一分解定理);试除只到 √n,剩下的 >1 就是质数;约数个数 = 各"指数+1"相乘。