【模板】質數判斷(Miller_Rabin)
阿新 • • 發佈:2018-08-06
整數 turn std 數字 include 需要 n) space break
題意簡述
給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內)
題解思路
費馬小定理: n是一個奇素數,a是任何整數(\(1≤ a≤n-1\)) ,則\(a^{p-1}≡1(mod\ p)\)。
推論:如果n是一個奇素數,則方程\(x^2 ≡ 1 (mod\ n)\)只有±1兩個解。
代碼
#include <cstdio> using namespace std; const int t[5] = {0, 2, 7, 61}; int n, m, x; int ksm(int a, int r, int mod) { if (r == 0) return 1; if (r == 1) return a; int x = ksm(a, r >> 1, mod) % mod; if (r & 1) return ((long long) x * x * a) % mod; else return ((long long) x * x) % mod; } bool mr(int x) { if (x == 1) return 0; int cnt = 0, p1 = x - 1; while (p1 % 2 == 0) { ++cnt; p1 /= 2; } for (int i = 1; i <= 3; ++i) { if (x == t[i]) return 1; int xx = ksm(t[i], p1, x); if (xx % x != 1 && xx % x != x - 1) { bool flag = 0; for (int j = 1; j <= cnt; ++j) { xx = (long long) xx * xx % x; if (xx == x - 1) { flag = 1; break; } } if (!flag) return 0; } } return 1; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; ++i) { scanf("%d", &x); if (mr(x)) puts("Yes"); else puts("No"); } }
【模板】質數判斷(Miller_Rabin)