首页 > 技术文章 > Miller-Rabin质数测试

zpj61 2020-08-21 21:17 原文

 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 }

 

推荐阅读