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


 

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

首先判斷這個數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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM