第41章 初等数论

第41章 初等数论

初等数论是研究整数性质的数学分支,其内容在程序设计中有着广泛应用,如密码学、算法优化、数据校验等。本章对应 GESP C++ 五级知识块 1:初等数论,覆盖大纲要求的全部考点:素数与合数、最大公约数与最小公倍数、同余与模运算、约数与倍数、质因数分解、奇偶性,以及欧几里得算法、唯一分解定理、埃氏筛法与线性筛法。

41.1 基本概念与性质

41.1.1 整除

定义:设 aa、bb 为整数,且 b≠0b \neq 0,若存在整数 kk 使得 a=b×ka = b \times k,则称 bb 整除 aa(或 aa 能被 bb 整除),记作 b∣ab \mid a。此时 bb 是 aa 的约数(因数),aa 是 bb 的倍数。

性质:

  1. 若 a∣ba \mid b 且 b∣cb \mid c,则 a∣ca \mid c(传递性)。
  2. 若 a∣ba \mid b 且 a∣ca \mid c,则对任意整数 mm、nn,有 a∣(m×b+n×c)a \mid (m \times b + n \times c)。
  3. 若 a∣ba \mid b 且 b∣ab \mid a,则 a=±ba = \pm b。
  4. 若 b∣ab \mid a,则 b∣a×kb \mid a \times k(kk 为任意整数)。

记忆要点:整除是"无余数的倍数关系",是约数、倍数、素数、合数等概念的共同基础。

41.1.2 素数与合数

  • 素数(质数):大于 1 的整数,若除了 1 和自身外没有其他正约数,则称为素数(如 2、3、5、7)。
  • 合数:大于 1 的非素数整数(如 4、6、8、9)。
  • 特殊规定:1 既不是素数也不是合数。

性质:

  1. 大于 2 的素数都是奇数。
  2. 任何大于 1 的整数都能分解为素数的乘积(算术基本定理)。

41.1.3 最大公约数与最小公倍数

最大公约数(GCD):设 aa、bb 为整数,若 dd 是同时整除 aa 和 bb 的最大正整数,则 dd 称为 aa 和 bb 的最大公约数,记作 gcd⁡(a,b)\gcd(a,b)。

  • 性质:gcd⁡(a,b)=gcd⁡(b,a mod b)\gcd(a,b) = \gcd(b, a \bmod b)(辗转相除法的理论基础)。
  • 互质定义:若 gcd⁡(a,b)=1\gcd(a, b) = 1,则称 aa 和 bb 互质(互素)。

最小公倍数(LCM):设 aa、bb 为正整数,若 mm 是同时是 aa 和 bb 的最小正倍数,则 mm 称为 aa 和 bb 的最小公倍数,记作 lcm⁡(a,b)\operatorname{lcm}(a, b)。

  • 性质:对任意正整数 aa、bb,有 a×b=gcd⁡(a,b)×lcm⁡(a,b)a \times b = \gcd(a, b) \times \operatorname{lcm}(a, b)。

41.1.4 奇偶性

  • 偶数:能被 2 整除的整数(n mod 2=0n \bmod 2 = 0);奇数:被 2 除余 1 的整数(n mod 2=1n \bmod 2 = 1)。
  • 运算规律(模 2 下恒成立):
    • 偶 ± 偶 = 偶,奇 ± 奇 = 偶,偶 ± 奇 = 奇;
    • 偶 × 任意 = 偶,奇 × 奇 = 奇。
  • 考试常见用途:判断整除性、构造配对、二分答案中的步长奇偶讨论、异或性质(a⊕a=0a \oplus a = 0,奇偶计数)等。

41.1.5 约数与倍数

  • dd 是 nn 的约数 ⇔ n mod d=0n \bmod d = 0。
  • 约数总是成对出现:若 d∣nd \mid n,则 nd\frac{n}{d} 也是约数,因此只需枚举到 n\sqrt{n} 即可找出所有约数。
  • 一个数的约数个数、约数之和可通过质因数分解快速求得(见 41.4.2)。

41.2 核心算法与实现

41.2.1 辗转相除法(欧几里得算法)求 GCD

辗转相除法不断用"余数"替换"较大数",直到余数为 0,最后一个非零余数就是最大公约数。

辗转相除法求 gcd(48,18)

// 迭代版:求 a 和 b 的最大公约数(a、b 为非负整数,且不同时为 0)
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}

// 递归版本
int gcdRecursive(int a, int b) {
if (b == 0) return a;
return gcdRecursive(b, a % b);
}

复杂度:每次取模至少让数值折半,时间复杂度 O(log⁡(min⁡(a,b)))O(\log(\min(a,b)))。

41.2.2 最小公倍数(LCM)的计算

// 求 a 和 b 的最小公倍数(a、b 为正整数)
int lcm(int a, int b) {
return a / gcd(a, b) * b; // 先除后乘,避免 a*b 溢出
}

41.2.3 素数判定(试除法)

判断一个数 nn 是否为素数,只需检查 2∼⌊n⌋2 \sim \lfloor\sqrt{n}\rfloor 之间的整数能否整除 nn。

// 判断 n 是否为素数(n >= 2)
bool isPrime(int n) {
if (n <= 1) return false;
if (n == 2) return true;
if (n % 2 == 0) return false; // 偶数一定不是素数
for (int i = 3; i * i <= n; i += 2) { // 只检查奇数
if (n % i == 0) return false;
}
return true;
}

41.2.4 埃氏筛法(筛选素数)

埃氏筛法是筛选 1∼n1 \sim n 所有素数的算法,时间复杂度 O(nlog⁡log⁡n)O(n \log \log n)。

// 返回标记数组,isPrime[i] 为 true 代表 i 是素数
vector<bool> sieveOfEratosthenes(int n) {
vector<bool> isPrime(n + 1, true);
isPrime[0] = isPrime[1] = false;
for (int p = 2; p * p <= n; p++) {
if (isPrime[p]) {
for (int i = p * p; i <= n; i += p) {
isPrime[i] = false;
}
}
}
return isPrime;
}

41.2.5 线性筛法(欧拉筛法)

线性筛时间复杂度 O(n)O(n),每个合数只会被其最小质因数标记一次,无重复操作。

// 线性筛,返回 1~n 内所有素数列表
vector<int> linearSieve(int n) {
vector<bool> isComposite(n + 1, false);
vector<int> primes; // 存储素数
for (int i = 2; i <= n; ++i) {
if (!isComposite[i]) {
primes.push_back(i); // i 是素数
}
// 用已找到的素数筛除合数
for (int p : primes) {
if (i * p > n) break;
isComposite[i * p] = true;
if (i % p == 0) break; // p 是 i 最小质因数,停止循环
}
}
return primes;
}

优势:

  1. 不会重复标记合数(如 6 仅被 2 标记,不会再被 3 标记),大数据效率更高;
  2. 可同步记录每个数字最小质因数,方便质因数分解。

41.2.6 分解质因数

算术基本定理:任意大于 1 整数可唯一分解为素数乘积。

#include <map>
// 将 n 分解,返回 {质因数: 指数} 映射
map<int, int> primeFactorization(int n) {
map<int, int> factors;
// 处理 2 的倍数
while (n % 2 == 0) {
factors[2]++;
n /= 2;
}
// 处理奇数因子
for (int i = 3; i * i <= n; i += 2) {
while (n % i == 0) {
factors[i]++;
n /= i;
}
}
// 剩余大于 2 的素数
if (n > 2) {
factors[n]++;
}
return factors;
}

41.3 同余与模运算

41.3.1 同余定义

若整数 aa 和 bb 除以 mm 余数相同,则称 aa 与 bb 模 mm 同余,记作 a≡b(modm)a \equiv b \pmod{m},等价于 m∣(a−b)m \mid (a - b)。

41.3.2 模运算性质

  1. (a+b) mod m=((a mod m)+(b mod m)) mod m(a + b) \bmod m = \big((a \bmod m) + (b \bmod m)\big) \bmod m
  2. (a−b) mod m=((a mod m)−(b mod m)+m) mod m(a - b) \bmod m = \big((a \bmod m) - (b \bmod m) + m\big) \bmod m(加 mm 避免负数)
  3. (a×b) mod m=((a mod m)×(b mod m)) mod m(a \times b) \bmod m = \big((a \bmod m) \times (b \bmod m)\big) \bmod m

快速幂(模幂运算)

高效计算 ab mod ma^b \bmod m,时间 O(log⁡b)O(\log b):

long long fastPower(long long a, long long b, long long m) {
long long result = 1;
a %= m;
while (b > 0) {
if (b % 2 == 1) {
result = (result * a) % m;
}
a = (a * a) % m;
b /= 2;
}
return result;
}

41.3.3 同余方程简介

最简同余方程 ax≡b(modm)a x \equiv b \pmod{m},有解充要条件:gcd⁡(a,m)∣b\gcd(a, m) \mid b。 若 gcd⁡(a,m)=1\gcd(a, m) = 1,存在模逆元 aϕ(m)−1(modm)a^{\phi(m)-1} \pmod{m}。

41.4 常用数论定理

41.4.1 算术基本定理

任意大于 1 整数 nn 可唯一分解:

n=p1k1×p2k2×⋯×pmkmn = p_{1}^{k_{1}} \times p_{2}^{k_{2}} \times \dots \times p_{m}^{k_{m}}

其中 p1<p2<⋯<pmp_1 < p_2 < \dots < p_m 为素数,kik_i 为对应指数。

41.4.2 唯一分解定理推论

设 a=p1a1p2a2…pkaka = p_1^{a_1} p_2^{a_2} \dots p_k^{a_k},b=p1b1p2b2…pkbkb = p_1^{b_1} p_2^{b_2} \dots p_k^{b_k},则

gcd⁡(a,b)=p1min⁡(a1,b1)p2min⁡(a2,b2)…pkmin⁡(ak,bk)\gcd(a,b) = p_1^{\min(a_1,b_1)} p_2^{\min(a_2,b_2)} \dots p_k^{\min(a_k,b_k)} lcm⁡(a,b)=p1max⁡(a1,b1)p2max⁡(a2,b2)…pkmax⁡(ak,bk)\operatorname{lcm}(a,b) = p_1^{\max(a_1,b_1)} p_2^{\max(a_2,b_2)} \dots p_k^{\max(a_k,b_k)}
  • 因数个数公式:若 nn 分解后指数为 k1,k2,…,kmk_1, k_2, \dots, k_m,则因数总数为 (k1+1)(k2+1)…(km+1)(k_1+1)(k_2+1)\dots(k_m+1)。
  • 示例:12=22×3112 = 2^2 \times 3^1,因数个数 (2+1)(1+1)=6(2+1)(1+1) = 6。

41.4.3 欧拉定理

若 gcd⁡(a,m)=1\gcd(a, m) = 1,则 aϕ(m)≡1(modm)a^{\phi(m)} \equiv 1 \pmod{m},ϕ(m)\phi(m) 代表 1∼m1 \sim m 中和 mm 互质数字总数。

41.4.4 费马小定理

若 pp 是素数,且 aa 不被 pp 整除,则 ap−1≡1(modp)a^{p-1} \equiv 1 \pmod{p}。 费马小定理是欧拉定理 mm 为素数时的特例(ϕ(p)=p−1\phi(p) = p-1)。

41.5 注意事项

  1. 数据溢出:大数运算使用 long long 替代 int。
  2. 边界:0 不能作为除数;1 非素数;2 是唯一偶素数。
  3. 模负数:C++ 中负数取模结果为负,需 (x % m + m) % m 转正。
  4. 筛法选择:小规模判断素数用试除,大范围批量筛素数用线性筛。
  5. 奇偶性:涉及整除、配对、异或计数时优先考虑奇偶性简化。

41.6 选择题练习

  1. 下列关于素数的说法,正确的是: A. 1 是素数 B. 大于 2 的素数都是奇数 C. 所有偶数都是合数 D. 素数只有有限个

    查看答案

    答案:B。1 既不是素数也不是合数(A 错);2 是偶数但不是合数(C 错);素数有无穷多个(D 错);除 2 外素数均为奇数,故 B 正确。

  2. 用辗转相除法求 gcd⁡(48,18)\gcd(48, 18),最后一个非零余数是: A. 2 B. 3 C. 6 D. 12

    查看答案

    答案:C。48=18×2+1248 = 18 \times 2 + 12,18=12×1+618 = 12 \times 1 + 6,12=6×2+012 = 6 \times 2 + 0,最后一个非零余数为 6,故 gcd⁡(48,18)=6\gcd(48,18)=6。

  3. 已知 gcd⁡(a,b)=6\gcd(a,b)=6 且 a×b=720a \times b = 720,则 lcm⁡(a,b)\operatorname{lcm}(a,b) 等于: A. 120 B. 60 C. 720 D. 4320

    查看答案

    答案:A。由 a×b=gcd⁡(a,b)×lcm⁡(a,b)a \times b = \gcd(a,b) \times \operatorname{lcm}(a,b),得 720=6×lcm⁡(a,b)720 = 6 \times \operatorname{lcm}(a,b),所以 lcm⁡(a,b)=120\operatorname{lcm}(a,b) = 120。

  4. 在 C++ 中,表达式 (-7) % 3 的结果最接近于以下哪个"转正"处理? A. 2 B. -1 C. 1 D. -2

    查看答案

    答案:B。C++ 中 (-7) % 3 的结果为 -1(符号与被除数相同)。要得到正余数 2,需写成 (-7 % 3 + 3) % 3。本题问"表达式本身的结果",故选 B。

  5. 用试除法判断 nn 是否为素数,只需检查到: A. n/2n/2 B. ⌊n⌋\lfloor\sqrt{n}\rfloor C. n−1n-1 D. ⌊n/3⌋\lfloor n/3 \rfloor

    查看答案

    答案:B。若 nn 有大于 n\sqrt{n} 的因子,则其对应配对因子必小于 n\sqrt{n},故只需检查到 ⌊n⌋\lfloor\sqrt{n}\rfloor 即可。

SShowball OI知识手册