143. 质数判定__模板题链接
前置知识
费马小定理: 是质数,则对于任意的 , 与 互质,则有 。
二次探测定理:如果 是一个质数, ,则有解为 ,推理如下
同样的我们即可反证:如果 ,并且 ,那么我们一定可以认定 不是质数。
miller_radin的实现
对于一个质数 ,我们显然可以得到 的形式, 是奇数。
我们在 中随机选取一个数 ,显然有 。
所以我们可以从 开始,做 次二次探测,如果二次探测失败,我们直接得到这个数不止质数,当二次探测完成时,我们再做一次费马小定理的特判,判断该数是不是质数。
miller_rabin 模板代码
ll quick_mult(ll a, ll b, ll mod) {
ll ans = 0;
while(b) {
if(b & 1) ans = (ans + a) % mod;
a = (a + a) % mod;
b >>= 1;
}
return ans;
}
ll quick_pow(ll a, ll n, ll mod) {
ll ans = 1;
while(n) {
if(n & 1) ans = quick_mult(ans, a, mod);
a = quick_mult(a, a, mod);
n >>= 1;
}
return ans;
}
bool miller_rabin(ll n) {
if(n == 2) return true;
if(n < 2 || !(n & 1)) return false;
ll s = 0, d = n - 1;
while(!(d & 1)) {
d >>= 1;
s++;
}
srand(time(0));
for(int i = 1; i <= 5; i++) {
ll a = rand() % (n - 2) + 2;
ll now = quick_pow(a, d, n), pre = now;
for(int j = 1; j <= s; j++) {
now = quick_mult(now, now, n);
if(now == 1 && pre != 1 && pre != n - 1) return false;
pre = now;
}
if(now != 1) return false;
}
return true;
}