你知道如何判定一个大整数为素数吗?——米勒拉宾素数判定算法

 

米勒拉宾算法的基本概念如下:

首先判断这个数n的奇偶性

若为偶数仅有2是质数

奇数则进入测试

测试方法:

首先确定几个基底a,范围在[2,n-1]

因为n是奇数,所以n-1必定为偶数

则n-1可以表示为(2^s)*d

s、d分别求出来

设t为a^d模n的数,有如下几个约定:

1.若t=-1或1时则该数n可能为质数

2.若此时t=n-1,则该数可能为质数

3.d*2>n-1时n必为合数

4.若上述皆不满足则让d*2,返回2

多组测试之后就能判断是否为质数,而且错误率相当低!!

 

 

不过想证明米勒拉宾的正确性还是很困难的

需要费马小定理等七七八八的数论

具体的可以百度

我就给于证明了~

直接上模板:

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define ll long long
 6 using namespace std;
 7 
 8 ll add_mod(ll a,ll b,ll mod){    //快乘法 基于快速幂的二分思想 
 9     ll ans=0;                    //由于考虑到取模数很大 快速幂会溢出 
10     while(b){                    //必须使用该方法 
11         if(b&1)                    //我这里写的是非递归版 
12             ans=(ans+a)%mod;
13         a=a*2%mod;
14         b>>=1;
15     }
16     return ans;
17 }
18 
19 ll pow_mod(ll a,ll n,ll mod){            //快速幂 递归版 
20     if(n>1){                            
21         ll tmp=pow_mod(a,n>>1,mod)%mod;
22         tmp=add_mod(tmp,tmp,mod);
23         if(n&1) tmp=add_mod(tmp,a,mod);
24         return tmp;
25     }
26     return a;
27 }
28 
29 bool Miller_Rabbin(ll n,ll a){//米勒拉宾素数判断函数主体
30     ll d=n-1,s=0,i;    
31     while(!(d&1)){            // 先把(2^s)*d 算出来 
32         d>>=1;
33         s++;
34     }
35     ll t=pow_mod(a,d,n);    //a^d取一次余判断 
36     if(t==1 || t==-1)        //一或负一则可以声明这可能是质数 
37         return 1;
38     for(i=0;i<s;i++){                //不是的话继续乘上s个2 
39         if(t==n-1)            //(n-1)*(n-1)%n=1 这一步是优化 
40             return 1;
41         t=add_mod(t,t,n);    // 快乘 
42     }
43     return 0;
44 }
45 
46 bool is_prime(ll n){
47     ll i,tab[4]={3,4,7,11};//本来应该取[1,n]内任意整数 
48     for(i=0;i<4;i++){                //但一般这几个数足以,不需要太多组测试 
49         if(n==tab[i])
50             return 1;        //小判断小优化~ 
51         if(!n%tab[i])
52             return 0;
53         if(n>tab[i] && !Miller_Rabbin(n,tab[i]))
54             return 0;
55     }
56     return 1;
57 }
58     
59 int main(){
60     ll n;
61     scanf("%lld",&n);
62     if(n<2) printf("No");
63     else if(n==2) printf("Yes");
64     else{
65         if(!n%2) printf("No");
66         else if(is_prime(n))
67             printf("Yes");
68         else printf("No");
69     }
70     return 0;
71 }
Miller_Rabbin

 

转载于:https://www.cnblogs.com/JVxie/p/4975876.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值