Miler_Rabin
\ (\ forall x <p \ ) exist:
- Fermat's little theorem: \ (X-P. 1} ^ {\ equiv1 \ PMOD P \)
- Secondary detection Theorem: \ (X ^ 2 \ equiv. 1 \ P PMOD \ Rightarrow X \ equiv1 \ or X \ equiv -1 \ PMOD P \)
Substrate
You can refer http://miller-rabin.appspot.com/ .
- \ (2,325,9375,28178,450775,9780504,1795265022 \) : at least \ (2 ^ {64} \) .
Code
inline int Miller_Rabin(i64 n) {
const i64 P[] = { ..., 0 };
if (n < 2) return 0;
i64 m = n - 1, a, b; int k = 0;
while (!(m & 1)) m >>= 1, ++k;
for (int i = 0; P[i]; ++i) {
if (!(a = P[i] % n)) return 1;
a = b = pow(a, m, n);
for (int j = 1; j <= k; ++j)
if ((b = mul(a, a, n)) == 1 && a != 1 && a != n - 1) return 0;
if (a != 1) return 0;
}
return 1;
}
i64 pow(i64 a, i64 k, i64 p) {
i64 t = 1;
for (; k; a = mul(a, a, p), k >>= 1) if (k & 1) t = mul(t, a, p);
return t;
}
i64 mul(i64 a, i64 b, i64 p) {
return ((a * b - (i64)((long double)a * b / p) * p) % p + p) % p;
}