[模板] miller

提交至 质数判定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

typedef long long ll;

ll (ll a, ll b, ll mod) {
return __int128(a)*__int128(b)%mod;
}

ll qpow(ll a, ll x, ll mod) {
ll ret = 1;
while (x) {
if (x & 1) ret = mul(ret, a, mod);
a = mul(a, a, mod);
x >>= 1;
}
return ret;
}

int prm[12] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};

ll miller_rabin(ll p) {
if (p == 2) return 1;
if (p == 1 || p % 2 == 0) return 0;
ll t = p-1, c = 0;
while (t % 2 == 0) {
t /= 2;
++ c;
}
for (int i = 0; i < 12 && prm[i] < p; i++) {
int a = prm[i];
ll v = qpow(a, t, p);
for (int j = 0; j < c; j++) {
ll nv = mul(v, v, p);
if (nv == 1 && v != 1 && v != p-1) return 0;
v = nv;
}
if (v != 1) return 0;
}
return 1;
}

int T;

int main() {
ll n;
while (scanf("%lld", &n) != EOF) {
if (miller_rabin(n)) puts("Y");
else puts("N");
}
return 0;
}