miller rabin (Fzu1649)

                                                    miller_rabin

 费马小定理:

            如果p是一个素数,且0<a<p ,则:

                                                             

            miller_rabin的出发点来自这个定理的逆否命题。

            如果mod 的结果不为 1,那么肯定不是素数。


二次探测定理:

  •      如果p是一个素数,且0<x<p ,则:

                                               

  •       如果p是一个素数  , p-1必是偶数,则:

                                                

  • 探测的过程:

                            

        在这个探测的过程运用二次探侧的逆否命题。

注意:这里的求解需要  快速幂

总结:


                   

                                                       应用于题目                
  • 题意与分析
        题意:判断一个大数的素性。

        分析:应用miller

  • 代码:


#include<cstdio>
#include<stdlib.h>
#define ll long long
#define times 2
ll random(ll n){
	return (ll)((double)rand()/RAND_MAX*n+0.5);
}
ll mult(ll a,ll b,ll n){
	ll ret=0;
	a%=n;
	while(b){
		if(b&1)
			ret=(ret+a)%n;	
		a=(a<<1)%n;
		b>>=1;
	}
	return ret;
}
ll quickmod(ll a,ll b,ll n){
	ll ret=1;
	a%=n;
	while(b){
		if(b&1)
			ret=mult(ret,a,n);
		a=mult(a,a,n);
		b>>=1;
	}
	return ret;
}
bool witness(ll a,ll n){
	ll m=n-1;
	int j=0;
	while(!(m&1)&&++j)m>>=1;
	ll x=quickmod(a,m,n);
	if(x==1)return 1;
	while(j--){
		if(x==n-1)return 1;
		x=mult(x,x,n);
	}
	return 0;
}
bool miller_rabin(ll n){
	int i;
	if(n==1)return 0;
	if(n==2)return 1;
	if(n%2==0)return 0;
	for(int i=1;i<=times;i++){
		ll a=random(n-2)+1;
		if(!witness(a,n))return 0;
	}
	return 1;
}
int main(){
	//for(int i=1;i<=100;i++)
	//	if(miller_rabin(i))printf("%d\n",i);
	ll n;
	while(~scanf("%I64d",&n)){
		if(miller_rabin(n))
			printf("It is a prime number.\n");
		else 
			printf("It is not a prime number.\n");
	} 
	return 0;
} 


猜你喜欢

转载自blog.csdn.net/kala0/article/details/79344077