關於Miller-Rabbin的一點想法
阿新 • • 發佈:2017-05-19
nbsp sca hide ace mil cnblogs n) bin stream
在好久之後終於搞完了miller-rabbin素性測試,談談自己的理解
要判斷的數設為 a,
主要思想就是運用費馬小定理來搞,隨機幾個數x(x<=a-1),判斷x^(a-1)=1(mod a)是否成立,如果有不成立,a肯定不是素數
這是有一定錯誤幾率的,隨機n個數的錯誤幾率為4^(-n)
這麽看來,肯定是多來幾組隨機數比較保險,10比較穩
期間加入了二次探測定理,以提高miller-rabbin的效率
二次探測定理:若p是奇素數 x^2=1 (mod p) x的解一定為 1或p-1
如果不滿足此定理,一樣是合數
code
1View Code#include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<queue> 5 #include<cmath> 6 #include<vector> 7 #include<cstdlib> 8 #include<iostream> 9 #include<ctime> 10 #define ll long long 11 #define inf 2147483647 12 #defineN 10 13 using namespace std; 14 15 ll quick_mul(ll a, ll b, ll n) { 16 ll res = 0; 17 while(b) { 18 if(b&1) res = (res + a) % n; 19 a = (a + a) % n; 20 b >>= 1; 21 } 22 return res; 23 } 24 25 ll quick_pow(ll a, ll b, ll n) { 26 ll res = 1; 27 while(b) { 28 if(b&1) res = quick_mul(res, a, n); 29 a = quick_mul(a, a, n); 30 b >>= 1; 31 } 32 return res; 33 } 34 bool miller_rabin(ll x){ 35 if(x==2||x==3||x==5||x==7||x==11)return 1; 36 if(x==1||!(x%2)||!(x%3)||!(x%5)||!(x%7)||!(x%11))return 0; 37 ll n=x-1;int k=0; 38 while(!(n&1)){n>>=1;k++;}//這麽做是為了順便加上二次探測定理 39 40 srand((ll)time(0)); 41 for(int i=1;i<=N;i++){ 42 ll t=rand()%(x-1)+1,pre; 43 if(!t)continue; 44 t=quick_pow(t,n,x); 45 pre=t; 46 for(int i=1;i<=k;i++){ 47 t=quick_mul(t,t,x); 48 if(t==1&&pre!=1&&pre!=x-1)return 0; 49 pre=t; 50 } 51 if(t!=1)return 0; 52 } 53 return 1; 54 55 } 56 57 58 int main(){ 59 //freopen(".in","r",stdin); 60 //freopen(".out","w",stdout); 61 int l,r,cnt=0; 62 scanf("%d%d",&l,&r); 63 for(int i=l;i<=r;i++){ 64 if(miller_rabin(i))cnt++; 65 } 66 printf("%d",cnt); 67 return 0; 68 }
關於Miller-Rabbin的一點想法