Miller–Rabin 素數測試
阿新 • • 發佈:2022-02-08
\(n\leq 2^{64}\) 即正確。
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<bitset> #define pb emplace_back #define mp std::make_pair #define fi first #define se second typedef long long ll; typedef __int128 i128; typedef long double ld; typedef unsigned long long ull; typedef std::pair<int, int> pii; typedef std::vector<int> vi; const ll mod = 998244353; ll Add(ll x, ll y) { return (x+y>=mod) ? (x+y-mod) : (x+y); } ll Mul(ll x, ll y) { return x * y % mod; } ll Mod(ll x) { return x < 0 ? (x + mod) : (x >= mod ? (x-mod) : x); } ll cadd(ll &x, ll y) { return x = (x+y>=mod) ? (x+y-mod) : (x+y); } ll cmul(ll &x, ll y) { return x = x * y % mod; } template <typename T> T Max(T x, T y) { return x > y ? x : y; } template<typename T, typename... T2> T Max(T x, T2 ...y) { return Max(x, y...); } template <typename T> T Min(T x, T y) { return x < y ? x : y; } template<typename T, typename... T2> T Min(T x, T2 ...y) { return Min(x, y...); } template <typename T> T cmax(T &x, T y) { return x = x > y ? x : y; } template <typename T> T cmin(T &x, T y) { return x = x < y ? x : y; } template <typename T> T &read(T &r) { r = 0; bool w = 0; char ch = getchar(); while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar(); while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar(); return r = w ? -r : r; } template<typename T1, typename... T2> void read(T1 &x, T2& ...y) { read(x); read(y...); } const int test[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 34}; i128 qpow(i128 x, i128 y, i128 mod) { i128 s = 1; while(y) { if(y & 1) s = s * x % mod; x = x * x % mod; y >>= 1; } return s; } bool Test(ll n, ll testnum) { int t = 0; ll x = n-1; while(!(x&1)) x >>= 1, ++t; i128 a = qpow(testnum, x, n); if(a == 1) return 1; for(int i = 0; i < t; ++i) { i128 lst = a; a = a * a % n; if(a == 1) return lst == n-1; } return 0; } bool check(ll x) { if(x < 2) return 0; for(auto a : test) if(x % a == 0) return x == a; for(auto a : test) if(!Test(x, a)) return 0; return 1; } signed main() { ll x; while(~scanf("%lld", &x)) { putchar(check(x) ? 'Y' : 'N'); putchar('\n'); } return 0; }