Miller-Rabin素性测试算法
Miller_rabin算法,优势可以单独判断一个大数是否素数。缺点他是一个不保证正确的算法,我们只能通过多次执行算法让这个错误的概率很小,不过幸运的是通常来看它的错误概率可以小到忽略不计。
Miller_rabin算法描述
![](https://img2018.cnblogs.com/blog/1674973/201908/1674973-20190814212701407-1034236385.png)
首先要知道费马定理只是n是素数的必要条件。即费马定理不成立,n一定是合数;费马定理成立,n可能是素数。接下来请看Miller-Rabin算法的分析过程。
1 #include <iostream> 2 #include <time.h> 3 #include <algorithm> 4 #include <stdio.h> 5 6 typedef long long LL; 7 8 using namespace std; 9 10 const int times = 20; 11 LL fac[1001]; 12 int cnt; 13 14 LL mul(LL a,LL b,LL mod){ 15 LL ans = 0; 16 while (b){ 17 if (b & 1){ 18 ans = (ans + a) % mod; 19 } 20 a = (a<<1) % mod; 21 b >>= 1; 22 } 23 return ans; 24 } 25 26 27 LL pow(LL a,LL b,LL mod){ 28 LL ans = 1; 29 while (b){ 30 if (b & 1){ 31 ans = mul(ans,a,mod); 32 } 33 b >>= 1; 34 a = mul(a,a,mod); 35 } 36 return ans; 37 } 38 39 40 bool witness(LL a,LL n){ 41 LL temp = n - 1; 42 int j = 0; 43 while (temp % 2 == 0){ // 其实就是得到 m 44 j++; 45 temp /= 2; 46 } 47 LL x = pow(a,temp,n); 48 if (x == 1 || x == n-1){ // 判断a^m 49 return true; 50 } 51 while (j--){ 52 x = mul(x,x,n); // 进一步判断 a^(2m) a^(4m) ... 53 if (x == n-1) 54 return true; 55 } 56 return false; 57 } 58 59 bool miller_rabin(LL n){ 60 if (n == 2){ // 如果是2肯定是素数 61 return true; 62 } 63 if (n<2 || n % 2 == 0){ //如果小于2或者是大于2的偶数肯定不是素数 64 return false; 65 } 66 for (int i=0;i<times;i++){ //随机化检验 67 LL a = rand() % (n-1) + 1; 68 if (!witness(a,n)) 69 return false; 70 } 71 return true; 72 } 73 74 int main(){ 75 LL tar; 76 while (cin >> tar){ 77 if (miller_rabin(tar)){ 78 cout << "Yes,Prime!" << endl; 79 } else 80 cout << "No" << endl; 81 } 82 return 0; 83 }