费马小定理及其简单应用
数论好玩,但显然大家都会以下的内容。
费马小定理
法国律师、业余数学家皮耶·德·费马告诉我们如下事实:
费马小定理:对于所有质数
p ,若正整数a 满足p \nmid a ,则a^{p-1}\equiv 1\pmod p 。
证明
首先我们可以证明
然后我们可以做一些小的推导:
第一个等号是显然的,第二个等号也不奇怪,第三个等号出自我们最初证明的结论。
这说明
另外这里有一些费马小定理的推论:
命题 A:对于所有质数
p ,若a 为正整数,则a^p\equiv a\pmod p 。
若
命题 B:对于所有质数
p ,若正整数a 与p 互质,则a^m\equiv a^{m\operatorname{mod}(p-1)}\pmod p 对所有正整数m 成立。
根据乘方的性质可以简单地证明。
Miller-Rabin 素性测试
这是由 CMU 的 Gary Lee Miller 教授发明,由以色列耶路撒冷希伯来大学的 Michael O. Rabin 教授改进的能在
(发明线性同余发生器的教授也叫 Miller,但他的全名是 Keith W. Miller。)
我们考虑费马小定理的逆定理,虽然它不成立,但如果对于足够多的
代码如下:
std::mt19937 mr(std::mt19937(time(0))); // 随机函数
int exp(int a, int b, int m) { // 快速幂
if(b==0) return 1;
int x(exp(a, b>>1, m));
x=(long long)x*x%m;
if(b&1) return (long long)x*a%m;
else return x;
}
bool isprime(int n) {
if(n<3) return n==2;
for(int i(1); i<=10; i++) { // 此处 k=10
int a(mr()%(n-2)+2);
if(exp(a, n-1, n)!=1) return 0;
}
return 1;
}
时间复杂度显然为
但这个算法的错误率有一点高,让我们来考虑优化。首先我们有一个引理:
二次探测定理:对于所有质数
p\gt 2 ,x^2\equiv 1\pmod p 的解有且仅有x\equiv 1 \pmod p 或x\equiv p-1 \pmod p 。
首先有
然后我们继续来考虑素性测试:根据二次探测定理,如果
改进后的代码(Miller-Rabin 算法):
bool isprime(long long n) {
if(n<4) return n==2 || n==3;
long long u(n-1), t(0);
while(!(u&1)) u>>=1, t++;
for(long long i(1); i<=7; i++) {
long long a(mr()%(n-3)+2); // 这里只取 [2, n-2] 之间的数,因为 1,2,n-1 都可以直接通过测试
long long v(exp(a, u, n));
if(v==1) continue;
long long s(0);
while(s<t) {
if(v==n-1) break;
s++;
v=(__int128)v*v%n;
}
if(s==t) return 0;
}
return 1;
}
求模意义下的乘法逆元
我们知道,对于质数
代码如下:
int inv(int x, int m) {
return exp(x, m-2, m);
}
本文参考了 oi-wiki 以及百度百科相关词条。