[miller_rabin]

miller_rabin

log(n)级别复杂度的判断素数的方式

费马小定理

对于任意整数\(a,p\)互质,则有$$a^{p-1}≡1(mod~p)$$

那么思考反过来可不可以?如果有\(a<p\)且满足这个式子,能不能说明\(p\)是质数呢?很遗憾,不可以,有些合数是可以满足这个式子的,它们被称为费马伪素数,最小的费马为素数是341,那么我们考虑既然有某个数\(a\)可以让费马伪素数\(p\)成立这个式子,那么把限制扩大,如果不是某个数\(a\)满足而是要求有多个数\(a\)都能使得\(p\)成立,那么能不能说明\(p\)是质数?通过多选取\(a\)的方式确实能筛选掉很多,但是不能完全筛掉,即遍历完\([2,p-1]\)也不能把它筛去,这样的合数称为卡迈尔数,而若\(n\)为卡迈尔数则\(2^n-1\)也为卡迈尔数,所以这样的数是无穷的。所以单单费马小定理是不足以判断素数的,故引入新的引理

二次探测定理

对于\(p\)是素数,若有$$x^2≡1(mod~p)$$ $$(x+1)(x-1)≡0(mod~p)$$ $$p|(x+1),p|(x-1)$$

则小于\(p\)的解只有$$x_1=1,x_2=p-1$$ 代入验证即可

那么再根据费马小定理将\(a^{p-1}\)看做\(x^2\)那么也必须满足上述式子。如果不满足那说明一定不是素数,如果将\(a^{p-1}\)看做\(x^2\)成立,那么再将\(a^{\frac{n-1}{2}}\)看做\(x^2\)看是否满足式子,直到\(p-1\)除以\(2\)除到奇数,这期间要么全是\(1\),要么出现\(p-1\)后然后全是\(1\)\(p-1\)不能出现在最后不然连费马小定理也不满足了

算法

假设\(n\)是一个质数,那么\(n-1\)是一个偶数,我们把\(n-1\)表示成\(d×2^s\)的形式,\(s\)\(d\)都是正整数且\(d\)是奇数,对任意在正整数内的\(a\)\(0≤r≤s-1\),必满足下列一个式子

\[a^d ≡ 1(mod~n) \]

\[a^{2^rd}≡n-1(mod~n) \]

\(tips\)\(Jim Sinclair\)发现了一组数:\(2, 325, 9375, 28178, 450775, 9780504, 1795265022\)。用它们做\(a\),在\(long long\)范围内不会出错

于是代码

#include <cstdio>
#include <iostream>
#include <algorithm>
typedef long long LL;
using namespace std;
int prime[8] = {2,3,5,7,13,29,37,89};//用来测试 

LL quickpower(LL a,LL b,LL p)
{
	LL res = 1;
	while(b)
	{
		if(b & 1)
			res = res * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return res % p;
}

bool miller_rabin(int a,int n)
{
	int d = n - 1,r = 0;
	while(!(d & 1))
	{
		d >>= 1;
		r ++;
	}
	LL x = quickpower(a,d,n);
	if(x == 1) return true;
	for(int i=0;i<r;i++)
	{
		if(x == n-1) return true;
		x = x * x % n;
	}
	return false;
}

//总之,若 n 是素数,则 a^d = 1(mod n) 
//或 存在0 ≤i < r使(a ^ (d * 2^i)) = n-1(mod n) 

bool is_prime(int n)
{
	if(n <= 1) return false;
	for(int i=0;i<=7;i++)
		if(n == prime[i]) return true;
	for(int i=0;i<=7;i++)
		if(!miller_rabin(prime[i],n)) return false;
	return true;
}

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		if(is_prime(n))
		{
			printf("%d是素数\n",n);
			continue;
		}
		else printf("%d不是素数\n",n); 
	}
	return 0;
}
posted @ 2021-09-02 20:00  -凨-  阅读(242)  评论(0)    收藏  举报