[模板] Miller_Rabin素数判断代码实现存档

就是....存存代码吧。
Miller_Rabin的最核心部分在于二次探测定理和费马小定理。后者在同余/逆元的题目里面或多或少都有提及吧.....前者也很简单。
总而言之,Miller_Rabin不算很难啦,值得去学习一下~

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int S=5;
ll qpow(ll x,ll k,ll mod){
	ll ret=1;
	while(k){
		if(k&1) ret=(ret*x)%mod;
		x=(x*x)%mod;
		k>>=1;
	}
	return ret;
}

bool miller_rabin(ll n){
	if(n<2) return false;
	if(n==2) return true; // 特判一波
	ll x,pre,u;
	int k=0;
	u=n-1;
	while(!(u&1)){
		k++, u>>=1;
	} // 取2位数
	for(int i=1;i<S;i++){ // 做S次判断
		x=rand()%(n-2)+2; // 随机取(2,n)的数,n若是质数,x肯定与n互质
		x=qpow(x,u,n); // 先算 x^u
		pre=x;
		for(int i=0;i<k;i++){
			x=(x*x)%n; // x^2,二次探测定理
			if(x==1 && pre!=1 && pre!=n-1) return false;
			pre=x;
		}
		if(x%n!=1)return false; // 费马小定理
	}
	return true;
}

int main(){
	ios::sync_with_stdio(false);
	srand(time(0));
	int m,na;
	cin>>m>>m;
	while(m--){
		cin>>na;
		if(miller_rabin(na)) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
}
posted @ 2017-11-09 08:12  ajcxsu  阅读(89)  评论(0编辑  收藏