如果 {a0,a1,⋯,am−1} 是模 m 的完全剩余系,那么对于满足 (b,m)=1 的 b,{b×a0,b×a1,⋯,b×am−1} 也是模 m 的完全剩余系。
证明:
运用反证法。
假设新的集合不是模 m 的完全剩余系,那么存在 b×ai 与 b×aj 使得:
b×ai≡b×aj(modm)
那么由于引理一,有:
ai≡aj(modm)
那么一开始的集合就也不是模 m 的完全剩余系,与已知条件矛盾。
所以新集合是模 m 的完全剩余系。
费马小定理的证明
易得 {0,1,2,⋯,p−1} 是一个模 p 的完全剩余系。
由于 (a,p)=1,根据引理二,{0,a,2a,⋯,(p−1)a} 也是模 p 的完全剩余系。
我们把两个集合的所有元素(除了 0)全部乘起来再取余,容易得到:
1×2×⋯×(p−1)≡a×2a×⋯×(p−1)a(modp)
即
(p−1)!≡(p−1)!×ap−1(modp)
由于 p 是质数,明显 (p−1)! 与 p 互质。
所以根据引理一,得到
ap−1≡1(modp)
得证。
费马小定理的应用
求乘法逆元是数论中一个很重要的板块。具体来讲,就是要求满足 a×b≡1(modm) 的 b,此时一般把 b 写作 a−1。
那么对于一个质数 p,对于与它互质的 a,有:
ap−1≡1(modp)a×ap−2≡1(modp)
所以:
ap−2≡a−1(modp)
这样再加上一个快速幂模板,我们就可以 O(logp) 求逆元了。
代码如下。
CPP
#include<bits/stdc++.h>usingnamespace std;
typedeflonglong ll;
ll a, p;
inline ll quick_power(ll a, ll b, ll mod){ // a 的 b 次方对 mod 取模
ll res = 1;
while (b) {
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
intmain(){
scanf("%lld%lld", &a, &p);
ll ins = quick_power(a, p - 2, p); // 求逆元printf("%lld\n", ins);
}
欧拉定理
对于两个数 a,m,如果 (a,m)=1,那么:
aφ(m)≡1(modm)
注意:这里的 m 不需要是质数。
什么是 φ(m)
欧拉函数 φ(m) 就是 1 到 m 中与 m 互质的个数,特别的,φ(1)=1。
例如:φ(6)=2,因为 (1,6)=1,(5,6)=1。
闲话
容易发现,如果 m 是质数,那么 φ(m)=m−1,所以我们说费马小定理是欧拉定理的特殊版本。
证明
不会证 qwq。
此处给一个感性的理解。
在费马小定理中,我们可以想象成有 p−1 个点,我们在 1 和 a(以下默认要取模)之间连一条有向边,在 a 和 a2 之间连一条有向边,以此类推,那么乘以 a 的操作就是通过有向边走到下一个顶点,那么从 1 开始走,经过所有边(p−1 条边)后回到原点,说明定理成立。
在欧拉定理中,由于 (a,m)=1,不断乘以 a 后得到的数肯定也与 m 互质,因此我们可以想象成有 φ(m) 个点,按照同样的方法连边,从 1 开始走,经过所有边(φ(m) 条边)后回到原点,说明定理成立。