poj 3641 快速冪+米勒羅賓判斷大素數
阿新 • • 發佈:2019-02-10
題意:
判斷一個數p是否滿足:
1.p不是素數;
2.pow_mod(a, p, p) == a % p。
程式碼:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #include <vector> #include <queue> #include <map> #include <climits> #include <cassert> #define LL long long #define lson lo, mi, rt << 1 #define rson mi + 1, hi, rt << 1 | 1 using namespace std; const int maxn = 1000001 + 10; const int inf = 0x3f3f3f3f; const double eps = 1e-8; const double pi = acos(-1.0); const double ee = exp(1.0); LL pow_mod(LL a, LL n, LL mod) { if (n == 0) return 1; LL x = pow_mod(a, n >> 1, mod); LL res = x * x % mod; if (n % 2) res = res * a % mod; return res; } bool Witness(LL a, LL n) { LL t = 0, m = n - 1; while (!(m & 1)) { t++; m >>= 1; } LL x = pow_mod(a, m, n); if (x == 1 || x == n - 1) return false; while (t--) { x = x * x % n; if (x == n - 1) return false; } return true; } const int Times = 11; bool Miller_Rabin(LL n) { if (n < 2) return false; if (n == 2) return true; if (!(n & 1)) return false; for (int i = 1; i <= Times; i++) { LL a = rand() % (n - 1) + 1; if (Witness(a, n)) return false; } return true; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAL LL p, a; while (~scanf("%lld%lld", &p, &a)) { if (!p && !a) break; if (!Miller_Rabin(p) && pow_mod(a, p, p) == a % p) { printf("yes\n"); } else { printf("no\n"); } } return 0; }