今天我们来介绍一下数论四大定理之三的费马小定理
费马小定理
如果 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方法比其他方法更占优势的一点就是,当一个数非常大的时候,能够较快的判定他的素性,使你的程序不会运行超时。