1 /** 2 Miller_Rabin 算法进行素数测试 3 快速判断一个<2^63的数是不是素数,主要是根据费马小定理 4 */ 5 #define ll __int128 6 const int S=8; ///随机化算法判定次数 7 ll MOD; 8 ///计算ret=(a*b)%c a,b,c<2^63 9 ll mult_mod(ll a,ll b,ll c) 10 { 11 a%=c; 12 b%=c; 13 ll ret=0; 14 ll temp=a; 15 while(b) 16 { 17 if(b&1) 18 { 19 ret+=temp; 20 if(ret>c) 21 ret-=c;//直接取模慢很多 22 } 23 temp<<=1; 24 if(temp>c) 25 temp-=c; 26 b>>=1; 27 } 28 return ret; 29 } 30 31 ///计算ret=(a^n)%mod 32 ll pow_mod(ll a,ll n,ll mod) 33 { 34 ll ret=1; 35 ll temp=a%mod; 36 while(n) 37 { 38 if(n&1) 39 ret=mult_mod(ret,temp,mod); 40 temp=mult_mod(temp,temp,mod); 41 n>>=1; 42 } 43 return ret; 44 } 45 46 ///通过费马小定理 a^(n-1)=1(mod n)来判断n是否为素数 47 ///中间使用了二次判断,令n-1=x*2^t 48 ///是合数返回true,不一定是合数返回false 49 bool check(ll a,ll n,ll x,ll t) 50 { 51 ll ret=pow_mod(a,x,n); 52 ll last=ret;//记录上一次的x 53 for(int i=1;i<=t;i++) 54 { 55 ret=mult_mod(ret,ret,n); 56 if(ret==1&&last!=1&&last!=n-1) 57 return true;//二次判断为是合数 58 last=ret; 59 } 60 if(ret!=1) 61 return true;//是合数,费马小定理 62 return false; 63 } 64 65 66 ///Miller_Rabbin算法 67 ///是素数返回true(可能是伪素数),否则返回false 68 bool Miller_Rabbin(ll n) 69 { 70 if(n<2) return false; 71 if(n==2) return true; 72 if((n&1)==0) return false;//偶数 73 ll x=n-1; 74 ll t=0; 75 while((x&1)==0) 76 { 77 x>>=1; 78 t++; 79 } 80 srand(time(NULL)); 81 for(int i=0;i<S;i++) 82 { 83 ll a=rand()%(n-1)+1; // 生成随机数 0<a<=n-1 去试试 84 if(check(a,n,x,t)) 85 return false; 86 } 87 return true; 88 }