题解 P4718/论 Miller-Rabin 算法的确定性化
前言
在刚开始学习 Miller-Rabin 的时候,我对算法本身的随机性感到相当程度的不满。
然后,百度百科上的一段话便吸引了我的注意。
卡内基梅隆大学的计算机系教授 Gary Lee Miller 首先提出了基于广义黎曼猜想的确定性算法,
由于广义黎曼猜想并没有被证明,其后由以色列耶路撒冷希伯来大学的 Michael O. Rabin 教授作出修改,
提出了不依赖于该假设的随机化算法。
于是便有了几个问题:
- 这个确定性算法到底是什么?
- 既然算法被随机化仅仅是因为广义黎曼猜想未被证明,
那么是否意味着它至少在 OI 范围内(2^{64} 以内) 是正确的,可以用于 OI? - 是否有简洁明快的方法,在 OI 范围内实现 确定性 判素?
相信不少初学者都有与我一样的问题,
这篇博文将介绍 Miller Rabin 算法及其确定性化,解决这几个疑问。
前置芝士:乘法逆元
费马素性检验
素性检验最暴力的方法是
具体的,我们有费马小定理:
若
p 为素数,对于所有的1\le a<p ,有a^{p-1}\equiv 1\pmod{p} 。
考虑它的逆否命题:
若存在
1\le a<p ,使得a^{p-1}\not\equiv 1\pmod{p} ,则p 一定不是素数。
那我们可以在
- 若存在快速幂的结果不是
1 ,则p 一定不是素数。 - 否则,
p 大概率是一个素数。
这一方法称为 费马素性检验 。
二次探测定理与 Miller Rabin 素性检验
遗憾的是,费马素性检验存在一个问题:
有的合数
这样的数被称为卡迈克尔数(Carmichael Number),又称为费马伪素数。
例如,
在
这迫使我们去优化费马素性检验。具体地,我们有二次探测定理:
若
p 为奇素数,则x^2\equiv 1\pmod{p} 的解为x\equiv\pm 1\pmod{p} 。
若
- 设选取的底数为
a ,初始化指数d=p-1 。 - 快速幂判定
a^d\bmod{p} 是否为1 ,不是1 则p 为合数。 - 否则,重复
d\leftarrow \dfrac{d}{2} 直到d 为奇数或a^d\not\equiv 1\pmod{p} - 最后,若
a^d\not\equiv\pm 1\pmod{p} ,则p 为合数,否则p 大概率是个素数。
typedef unsigned long long ull;
typedef unsigned int word;
bool check(const word a,const ull p){
ull d=p-1,get=pow(a,d,p);
if(get!=1) return 1;//特判 d=p-1 的情况
while((d&1)^1)
if(d>>=1,(get=pow(a,d,p))==p-1) return 0;//先 d/=2,再计算快速幂
else if(get!=1) return 1;
return 0;
}
初学者写 Miller-Rabin 时可能会犯的错误:
- 没有特判
2^{p-1}\equiv -1\pmod{p} 的情况。 - 先计算
a^d\bmod{p} ,再d\leftarrow \dfrac{d}{2} ,导致忽略了d 为奇数的情况。
若随机选取
也就是说,选取
固定底数与确定性检验
Miller-Rabin 的时间复杂度为
在 OI 的
如果我们假设广义 Riemann 猜想(GRH)成立,那么证明
n 是素数就只需要验证
“n 可以通过以2,3,4,\cdots \lfloor 2(\log n)^2\rfloor 为底的 Rabin-Miller 测试 ”了。
这个算法,如果能严格证明的话,运行时间是O((\log n)^5) 。
——摘自知乎回答如何编程判断一个数是否是质数?
(也就是前十二个质数)作为底数即可,它适用于
对于选取前
由此我们得到了最终的固定判素的代码(需要 C++ 11):
typedef unsigned long long ull;
typedef unsigned char byte;
const byte test[]={2,3,5,7,11,13,17,19,23,29,31,37};
bool miller_rabin(const ull p){
if(p>40){
for(word a:test)
if(check(a,p)) return 0;
return 1;
}
for(word a:test)
if(p==a) return 1;
return 0;
}
参考资料
- 知乎回答如何编程判断一个数是否是质数?
- 维基百科
- Deterministic variants of the Miller-Rabin primality test
希望借我这篇博文,确定性判素的 miller-rabin 能在 OI 中普及。
望大家学习时不要人云亦云、浅尝辄止。