-
Notifications
You must be signed in to change notification settings - Fork 1
/
Miller Rabin Faster
51 lines (49 loc) · 1.1 KB
/
Miller Rabin Faster
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
inline ll mulmod(ll base, ll mul, ll modulo)
{
ll ret = 0;
while(mul > 0){
if(mul%2==1) ret = (ret + base) % modulo;
base = (base + base) % modulo;
mul /= 2;
}
return (ret + modulo) % modulo;
}
inline ll bigmod(ll a, ll p, ll m)
{
ll ret = 1;
while(p)
{
if(p & 1) ret = mulmod(ret, a, m);
a = mulmod(a, a, m);
p /= 2;
}
return ret;
}
inline bool miller(ll p, int iter = 20)
{
if(p==3 || p==2 || p==5) return true;
if(p%2==0) return false;
if(p < 3) return false;
mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());
for(int i = 0; i<iter; i++)
{
ll a = (rnd()) % (p-4) + 2;
ll s = p-1;
while(s % 2 == 0) s/=2;
ll mod = bigmod(a, s, p);
if(mod==1 || mod==p-1) continue;
bool flag = 0;
s *= 2;
while(s != p-1)
{
mod = mulmod(mod, mod, p);
if(mod == p-1){
flag = 1;
break;
}
s *= 2;
}
if(flag==0) return 0;
}
return 1;
}