数论学习之五——费马小定理(米勒罗宾判素)

今天我们来介绍一下数论四大定理之三的费马小定理
费马小定理
如果 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) ap11(mod p).

证明如下:
p − 1 p-1 p1个整数 a , 2 a , . . . , ( p − 1 ) a a,2a,...,(p-1)a a,2a,...,(p1)a是个不能被 p p p整除,且其中任何两个数模 p p p不同余。所以, p − 1 p-1 p1个整数 a , 2 a , . . . , ( p − 1 ) a a,2a,...,(p-1)a a,2a,...,(p1)a p p p的余数为 1 , 2 , . . . , p − 1 1,2, ..., p-1 1,2,...,p1.因此 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) a2a...(p1)a12....(p1)(mod p)
a p − 1   ∗   ( p − 1 ) ! ≡ ( p − 1 ) ! ( m o d   p ) a^{p-1}\ *\ (p-1)!\equiv(p-1)!(mod\ p) ap1  (p1)!(p1)!(mod p).
因为 g c d ( ( p − 1 ) ! , p ) = 1 gcd((p-1)!, p)=1 gcd((p1)!,p)=1,所以 a p − 1 ≡ 1 ( m o d   p ) a^{p-1}\equiv1(mod\ p) ap11(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) an11(mod n),则n较大概率为素数。

准确的说 M i l l e r − R a b i n Miller-Rabin MillerRabin方法是一种随机化算法,设n为待检验的整数,k为选取a的次数。重复k次计算,每次在 [ 1 , n − 1 ] \left[1,n-1\right] [1,n1]范围内选取一个a。
a n − 1 m o d   n ≠ 1 a^{n-1}mod\ n \not=1 an1mod n=1,则n为合数(合数是指自然数中除了能被1和本身整除外,还能被其他数(0除外)整除的数);若随机选取的k个数都能够使 a n − 1 m o d   n = 1 a^{n-1}mod\ n =1 an1mod n=1成立,则返回n为素数。

下面我们给出 M i l l e r − R a b i n Miller-Rabin MillerRabin方法的模板:

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 MillerRabin方法比其他方法更占优势的一点就是,当一个数非常大的时候,能够较快的判定他的素性,使你的程序不会运行超时。

你可能感兴趣的:(数论)