-
Notifications
You must be signed in to change notification settings - Fork 438
/
Miller-Rabin.cpp
56 lines (48 loc) · 908 Bytes
/
Miller-Rabin.cpp
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 <cstdlib>
#define LOWBIT(x) ((x) & (-(x)))
#define COMPOSITE 0
#define PRIME 1
typedef long long ll;
using namespace std;
ll qpow(ll x, int y, int p)
{
if (y == 0) return 1;
ll h = qpow(x * x % p, y >> 1, p);
if ((y & 1) == 0) return h;
else return h * x % p;
}
bool witness(int a, int n)
{
int t = LOWBIT(n - 1);
int u = n / t;
ll x = qpow(a, u, n);
for (int i = 1; i < t; i <<= 1)
{
ll r = x * x % (ll)n;
if (r == 1 && x != 1 && x != n - 1) return true;
x = r;
}
if (x != 1) return true;
return false;
}
bool Miller_Rabin(int n, int s)
{
if (n == 2) return PRIME;
if ((n & 1) == 0) return COMPOSITE;
while (s--)
{
if (witness(rand() % (n - 2) + 2, n) == true) return COMPOSITE;
}
return PRIME;
}
int main()
{
int n;
while (true)
{
scanf("%d", &n);
printf("%s\n", Miller_Rabin(n, 10) == COMPOSITE ? "COMPOSITE" : "PRIME");
}
return 0;
}