大素數測試的Miller-Rabin算法


Miller-Rabin算法本質上是一種概率算法,存在誤判的可能性,但是出錯的概率非常小。出錯的概率到底是多少,存在嚴格的理論推導。

一、費馬小定理

假如p是質數,且gcd(a,p)=1,那么 a(p-1)≡1(mod p)

如果存在a<p,且a(p-1) % p != 1,則p肯定不是素數。

二、有限域上的平方根定理

三、Miller-Rabin算法

對於一個大數n,判斷n是不是素數的時候,可以先考慮a(n-1)≡ 1(mod n)

對於n-1,一定可以拆分成2s+d:

可以從x = ad開始,依次平方s次,每次平方的時候模上n,按照之前的平方根定理,如果模上n的結果為1的話,那么x一定是1,或者是n-1,如果不滿足則不是素數,x=x2,再次循環。

每次隨機選一個在2-n-1的數字作為a,可以重復測試。

由於mod上的是n,n是一個大數,所以快速冪中的乘法,需要用快速加法來實現。不然就算模上之后再相乘也會溢出。

 

 

 1 #include<iostream>
 2 #include<ctime>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn = 1000000+10;
 7 ll mul(ll a, ll b, ll m)
 8 //求a*b%m
 9 {
10     ll ans = 0;
11     a %= m;
12     while(b)
13     {
14         if(b & 1)ans = (ans + a) % m;
15         b /= 2;
16         a = (a + a) % m;
17     }
18     return ans;
19 }
20 ll pow(ll a, ll b, ll m)
21 //a^b % m
22 {
23     ll ans = 1;
24     a %= m;
25     while(b)
26     {
27         if(b & 1)ans = mul(a, ans, m);
28         b /= 2;
29         a = mul(a, a, m);
30     }
31     ans %= m;
32     return ans;
33 }
34 bool Miller_Rabin(ll n, int repeat)//n是測試的大數,repeat是測試重復次數
35 {
36     if(n == 2 || n == 3)return true;//特判
37     if(n % 2 == 0 || n == 1)return false;//偶數和1
38 
39     //將n-1分解成2^s*d
40     ll d = n - 1;
41     int s = 0;
42     while(!(d & 1)) ++s, d >>= 1;
43     srand((unsigned)time(NULL));
44     for(int i = 0; i < repeat; i++)//重復repeat次
45     {
46         ll a = rand() % (n - 3) + 2;//取一個隨機數,[2,n-1)
47         ll x = pow(a, d, n);
48         ll y = 0;
49         for(int j = 0; j < s; j++)
50         {
51             y = mul(x, x, n);
52             if(y == 1 && x != 1 && x != (n - 1))return false;
53             x = y;
54         }
55         if(y != 1)return false;//費馬小定理
56     }
57     return true;
58 }
59 int main()
60 {
61     int T;
62     cin >> T;
63     ll n;
64     while(T--)
65     {
66         cin >> n;
67         if(Miller_Rabin(n, 50))cout<<"Yes"<<endl;
68         else cout<<"No"<<endl;
69     }
70 }

 


免責聲明!

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



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