今天我们来介绍一下数论四大定理之三的费马小定理
费马小定理
如果
p
p
p是素数,
a
a
a是正整数,且
g
c
d
(
a
,
p
)
=
1
gcd(a,p)=1
gcd(a,p)=1,则
a
p
−
1
≡
1
(
m
o
d
p
)
a^{p-1}\equiv1(mod\ p)
ap−1≡1(mod p).
证明如下:
p
−
1
p-1
p−1个整数
a
,
2
a
,
.
.
.
,
(
p
−
1
)
a
a,2a,...,(p-1)a
a,2a,...,(p−1)a是个不能被
p
p
p整除,且其中任何两个数模
p
p
p不同余。所以,
p
−
1
p-1
p−1个整数
a
,
2
a
,
.
.
.
,
(
p
−
1
)
a
a,2a,...,(p-1)a
a,2a,...,(p−1)a模
p
p
p的余数为
1
,
2
,
.
.
.
,
p
−
1
1,2, ..., p-1
1,2,...,p−1.因此
a
∗
2
a
∗
.
.
.
∗
(
p
−
1
)
a
≡
1
∗
2
∗
.
.
.
.
∗
(
p
−
1
)
(
m
o
d
p
)
a*2a* ...*(p-1)a\equiv1*2* ....*(p-1)(mod\ p)
a∗2a∗...∗(p−1)a≡1∗2∗....∗(p−1)(mod p)
即
a
p
−
1
∗
(
p
−
1
)
!
≡
(
p
−
1
)
!
(
m
o
d
p
)
a^{p-1}\ *\ (p-1)!\equiv(p-1)!(mod\ p)
ap−1 ∗ (p−1)!≡(p−1)!(mod p).
因为
g
c
d
(
(
p
−
1
)
!
,
p
)
=
1
gcd((p-1)!, p)=1
gcd((p−1)!,p)=1,所以
a
p
−
1
≡
1
(
m
o
d
p
)
a^{p-1}\equiv1(mod\ p)
ap−1≡1(mod p)
费马小定理在ACM中一个非常显著的应用就是米勒罗宾判素 ,米勒罗宾判素是根据的费马小定理的逆定理来判别,虽然我们知道费马小定理的逆定理是不成立的,但是从大量数据来看,如果满足 g c d ( a , n ) = 1 gcd(a,n)=1 gcd(a,n)=1且 a n − 1 ≡ 1 ( m o d n ) a^{n-1}\equiv1(mod\ n) an−1≡1(mod n),则n较大概率为素数。
准确的说
M
i
l
l
e
r
−
R
a
b
i
n
Miller-Rabin
Miller−Rabin方法是一种随机化算法,设n为待检验的整数,k为选取a的次数。重复k次计算,每次在
[
1
,
n
−
1
]
\left[1,n-1\right]
[1,n−1]范围内选取一个a。
若
a
n
−
1
m
o
d
n
≠
1
a^{n-1}mod\ n \not=1
an−1mod n=1,则n为合数(合数是指自然数中除了能被1和本身整除外,还能被其他数(0除外)整除的数);若随机选取的k个数都能够使
a
n
−
1
m
o
d
n
=
1
a^{n-1}mod\ n =1
an−1mod n=1成立,则返回n为素数。
下面我们给出 M i l l e r − R a b i n Miller-Rabin Miller−Rabin方法的模板:
typedef long long ll;
ll q_pow(ll a, ll b, ll m) //快速幂取模
{
ll ans = 1;
while(b)
{
if(b&1)
{
ans *= a;
ans %= m;
}
a *= a;
a %= m;
b >>= 1;
}
return ans;
}
bool Miller_Rabin(ll x, ll n)//Miller-Rabin方法,选取x为底,判定n是否为素数
{
ll y = n - 1;
while(!(y&1))
y >>= 1;
x = q_pow(x, y, n);
while(y < n - 1 && x != 1 && x != n -1)
{
x = (x * x) % n;
y <<= (ll)1;
}
return x == n - 1 || y & 1 == 1;//若x为n-1或y为奇数,则n是素数,否则是合数
}
bool isprime(ll n) //判断32位内的整数是否为素数
{
if(n == 2 || n == 7 || n == 61)//若n为2,7,61内的数,则n为素数
{
return 1;
}
if(n == 1 || (n & 1) == 0) //若n为1或者是偶数,则n为合数
return 0;
return Miller_Rabin(2, n)&&Miller_Rabin(7, n)&&Miller_Rabin(61, n);
//对n进行以2,7,61为底的Miller-Rabin测试,如果通过,则n为素数,否则为合数。
}
这种模板适用的条件很多, M i l l e r − R a b i n Miller-Rabin Miller−Rabin方法比其他方法更占优势的一点就是,当一个数非常大的时候,能够较快的判定他的素性,使你的程序不会运行超时。