你知道如何斷定一個大整數爲素數嗎?——米勒拉賓素數斷定算法

 

米勒拉賓算法的基本概念以下:ios

首先判斷這個數n的奇偶性算法

若爲偶數僅有2是質數ide

奇數則進入測試函數

測試方法:測試

首先肯定幾個基底a,範圍在[2,n-1]優化

由於n是奇數,因此n-1一定爲偶數spa

則n-1能夠表示爲(2^s)*dcode

s、d分別求出來blog

設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
相關文章
相關標籤/搜索