1. 程式人生 > 實用技巧 >Miller-Rabin質數測試

Miller-Rabin質數測試

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 typedef long long LL;
 8 LL mul_mod(LL a,LL b,LL mod){
 9     LL ret=0;
10     while(b){
11         if(b&1)    ret=ret+a;
12         if(ret>=mod)    ret-=mod;
13 a=a+a; 14 if(a>=mod) a-=mod; 15 b>>=1; 16 } 17 return ret; 18 } 19 LL pow_mod(LL a,LL b,LL mod){ 20 LL ret=1; 21 while(b){ 22 if(b&1)ret=mul_mod(ret,a,mod); 23 a=mul_mod(a,a,mod); 24 b>>=1; 25 } 26 return
ret; 27 } 28 bool Miller_Rabin(LL n){//判斷素數 29 LL u=n-1,pre,x; 30 int i,j,k=0; 31 if(n==2||n==3||n==5||n==7||n==11) return true; 32 if(n==1||(!(n%2))||(!(n%3))||(!(n%5))||(!(n%7))||(!(n%11))) return 33 false;//初始化判斷素數 34 for(;!(u&1);k++,u>>=1);//按照要求轉換形式 35 for
(i=0;i<5;i++){ 36 x=rand()%(n-2)+2;//生成隨機數 37 x=pow_mod(x,u,n); 38 pre=x; 39 for(j=0;j<k;j++){ 40 x=mul_mod(x,x,n); 41 if(x==1&&pre!=1&&pre!=(n-1))//二次探測判斷 42 return false; 43 pre=x; 44 } 45 if(x!=1) return false;//用費馬小定理判斷 46 } 47 return true; 48 } 49 int main(){ 50 LL n,T; 51 scanf("%lld",&T); 52 while(T--){ 53 scanf("%lld",&n); 54 if(Miller_Rabin(n)) puts("Yes"); 55 else puts("No"); 56 } 57 return 0; 58 }