Miller–Rabin 素数测试
\(n\leq 2^{64}\) 即正确。
#include
#include
#include
#include
#include
#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 pii;
typedef std::vector 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 T Max(T x, T y) { return x > y ? x : y; }
template T Max(T x, T2 ...y) { return Max(x, y...); }
template T Min(T x, T y) { return x < y ? x : y; }
template T Min(T x, T2 ...y) { return Min(x, y...); }
template T cmax(T &x, T y) { return x = x > y ? x : y; }
template T cmin(T &x, T y) { return x = x < y ? x : y; }
template
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
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;
}