借鉴:https://blog.csdn.net/qq_24451605/article/details/47045279
借鉴:https://blog.csdn.net/qq_24451605/article/details/47045135
借鉴:https://blog.csdn.net/hzj1054689699/article/details/80693756
说明:
- 质因子(或质因数)在数论里是指能整除给定正整数的质数。比如360 = 23 * 32 * 5,质因子就是2,3,5。
- 除了1以外,两个没有其他共同质因子的正整数称为互质。
- 若 gcd(a, b) == 1,a, b互质。
- 若 gcd(a, c) == 1,gcd(b, c) == 1,则有 gcd(a * b, c) == 1。因为相乘以后还是没有公因子。
- 若 gcd(a, d) == 1,a = b * c,则有 gcd(b, d) == 1,gcd(c, d) == 1。因为整体既然没有公因子,部分也必然不会有。
欧拉函数的推导和证明:
欧拉函数,φ(n),或表示为phi(n),表示1~n中与n互质的数的个数。
推导:
设 p 为 n 的一个质因子。
令 m = n / p。
当 m % p == 0 时:
φ(n) = φ(m) * p
当 m % p != 0 时:
φ(n) = φ(m) * (p - 1)
证明:
首先,由于 n = m * p,所以所有与 n 互质的数必然同时与 m 和 p 互质;其次,所有即与 m 互质,也与 p 互质的数,都与 n 互质;最后,所有不满足即与 m 互质,也与 p 互质的数必然不与 n 互质。
于是,问题就从“在 1~n 中找与 n 互质的数的个数。”变成“在 1~n 中找即与 m 互质,也与 p 互质的数的个数。”。
正式开始证明:
我们先把 1~n 中所有与 m 互质的数全部找出来。
为此我们把 1~n 划分为 p 个区间,每个区间长度为 m,第 i 个区间表示为 (m * (i - 1), m * i],左开右闭,1 <= i <= p。
设第 i 个区间上第 j 个数为 xij ,则 xij = m * (i - 1) + j,1 <= j <= m。
要判断 xij 是否与 m 互质,只需要看 gcd(m, xij) 是否等于1。
又 gcd(m, xij) = gcd(m, j)。(欧几里德算法)
所以要求第 i 个区间上与 m 互质的数的个数只需要计算有多少个 j 满足 gcd(m, j) == 1,即 1~m 中有多少个数与 m 互质,很显然,答案是 φ(m)。
而这样的区间有 p 个,所以 1~n 中所有与 m 互质的数的个数为 φ(m) * p 个。
若所有与 m 互质的数都与 p 互质,则必有 m % p == 0,并且为充要条件,证明如下:
必要性:
若 m % p != 0,结合 p 是素数可知 gcd(m, p) == 1。
设 x 为 1~n 中某个与 m 和 p 互质的数。
则有 gcd(x, m) == 1,gcd(x, p) == 1。
∵ gcd(m, p) == 1。
∴ gcd(x * p, m) == 1。
∴ gcd(x * p, p) == 1 与题设矛盾。
充分性:
∵ m % p == 0。
∴ 必然存在一个整数 k ,使得 m = k * p。
设 x 为 1~n 中某个与 m 互质的数。
∴ gcd(x, m) == 1。
∴ gcd(x, p) == 1。
∴ 得证。
真正的证明开始了:
设 x 为 1~n 中某个与 m 互质数。
若 m % p == 0,“在 1~n 中找即与 m 互质,也与 p 互质的数的个数”即为“在 1~n 中找与 m 互质的数的个数”,因此 φ(n) = φ(m) * p。
若 m % p != 0,需要从所有与 m 互质的数中剔除掉与 p 不互质的数,因为 p 是质数,所以需要剔除掉有因子 p 的数。1~n 中所有含因子 p 的数所构成的集合为 {i * p | 1 <= p <= m},又因为 m 与 p 互质,所以判断 m 与 i * p 是否互质只需要判断 m 与 i 是否互质即可,是不是有点眼熟,这不就是 φ(m) 吗!因此 φ(n) = φ(m) * (p - 1)。
欧拉函数的推论:
对于素数 n ,φ(n) = n -1 。
对于两个不同素数 p, q ,它们的乘积 n = p * q 满足 φ(n) = (p -1) * (q -1) 。
欧拉定理:
如果 a 和 n 互质,那么aφ(n) ≡ 1 (mod n)。
证明:
设 x1, x2,……xφ(n)为 1~n 内与 n 互质的质数序列。
令 p1 = a * x1,p2 = a * x2,……,pφ(n) = a * xφ(n)。
以下先证明2个命题:
命题1:p 之间两两模 n 不同余。
假设 pi ≡ pj (mod n)(i > j)。
∴ pi - pj ≡ 0 (mod n)。
∴ a * (xi - xj) ≡ 0 (mod n)。
∵ 1 <= (xi - xj) < n
∴ a 必为 n 的倍数,这与 a 与 n 互质矛盾。
∴ 命题得证。
命题2:gcd(pi % n, n) == 1。
∵ gcd(a, n) == 1,gcd(xi, n) == 1。
∴ gcd(a * xi, n) == 1。
∴ gcd(pi % n, n) == 1。(欧几里德算法)
通过以上2个命题的证明,我们可以知道 pi 模 n 的余数两两不相同,一共有 φ(n) 个,且全部与 n 互质。这意味着所有 pi 模 n 的余数所组成的集合刚好就是集合{xi | 1 <= i <= φ(n)},也就是说,对于一个确定的 pi ,一定有唯一与之对应的 xj ,使得 pi ≡ xj (mod n)(i != j)。把所有等式两边对应的数都乘起来,我们就可以得到 p1 * p2 * …… * pφ(n) ≡ x1 * x2 * …… * xφ(n) (mod n)。两边消去 xi ,得到 aφ(n) ≡ 1 (mod n)。
费马小定理:
如果 a 和 p 互质且 p 为素数,那么ap-1 ≡ 1 (mod p)。
证明:
当 p 为素数时,φ(p) = p - 1,所以ap-1 ≡ 1 (mod p)。
利用费马小定理求逆元:
∵ ap-1 ≡ 1 (mod p)。
∴ ap-2 ≡ inv(a) (mod p)。
代码如下:
1 // Calculate x^y % p 2 inline LL pow_mod(LL x, LL y, LL p){ 3 LL ans = 1; 4 while(y){ 5 if(y & 1) ans = (ans * x) % p; 6 x = (x * x) % p; 7 y >>= 1; 8 } 9 return ans; 10 } 11 12 //费马小定理求a关于p的逆元 13 /** 14 * 费马小定理 15 * a^(p-1) ≡1 (mod p) 16 * a^(p-2) ≡1/a (mod p) 17 * a^(p-2) ≡ inv(a) (mod p) 18 */ 19 LL Fermat(LL a, LL p){ 20 return pow_mod(a, p-2, p); 21 }