Miller Rabin 判素

数学

费马小定理

对于素数 pp 必存在

ap11(modp) a^{p-1} \equiv 1 \pmod{p}

所以可以随机选取 a[2,n1]a\in[2,n-1] 检验是否满足上式,若不满足,则必然是合数

遗憾的是,存在无穷多个 nn,可以满足

 x[2,n1]xn11(modn) \forall\ x\in[2,n-1]\\ x^{n-1}\equiv 1 \pmod{n}

也就是说使费马判素失效

二次探测定理

素数 pp 必满足方程

x21(modp) x^2\equiv1\pmod{p}

有且仅有两个解

x11, x2p1(modp) x_1\equiv1,\ x_2\equiv p-1\pmod{p}

实现

n1n-1 分解成 d2td\cdot2^t 使 tt 尽量大

然后 xbased(modn)x\equiv base^{d} \pmod{n}

然后不断进行二次探测

即如果满足 x≢1x\not\equiv 1x≢n1x\not\equiv n-1x21x^2\equiv 1 那么这个数解不是素数了

最后进行费马判素

1
2
3
4
5
6
7
8
9
10
11
12
13
bool miller_rabin(ll n) {
if (n <= 2) return n == 2;
int d = n - 1, t = 0;
while (d % 2 == 0) d /= 2, ++t;
rep(i, 0, T) { // T 是测试次数, p 是测试基
ll x = ksm(p[i] % (n - 2) + 2, d, n);
if (x == 1 || x == n - 1) continue; // 无效的二次探测
for (int j = 0; j < t; ++j, x = x * x % n)
if (x != n - 1 && x != 1 && x * x % n == 1) return 0;
if (x != 1) return 0; // 费马判素
}
return 1;
}

这是测试基选择的推荐

数据范围 测试基
2322^{32} 2,7,61
2642^{64} 2,3,5,7,11,13,17,19,23,29,31,37
作者

Gesrua

发布于

2019-05-18

更新于

2020-11-21

许可协议