Miller-Rabin 素数检验算法

算法简介

Miller-Rabin算法,这是一个很高效的判断质数的方法,可以在用O(logn) 的复杂度快速判断一个数是否是质数。它运用了费马小定理和二次探测定理这两个筛质数效率极高的方法。

费马小定理判质数

ap1  1 mod p

这个定理在 p 为质数的时候是成立的,所以我们可以如果要判断 p 是否是质数,可以 rand 几个 a 值然后照着这个式子来算,如果算出来不是 1 那说明 p 一定不是质数。

但在我们的自然数中,如果照着这个式子算出来的答案为1,也是有可能不是质数的。更有一类合数,它用费马小定理不管 rand 什么数都判不掉。这类合数称为 Carmichael数(卡迈克尔数),其中一个例子就是561(哇,居然这么小)。

二次探测定理

因为Carmichael数的存在,使得我们难以高效判断质数,所以我们还需要加入第二种判断方法使这种伪算法更优秀!而二次探测无疑就是为我们量身定制的算法,因为它要建立在同余式右边为1的基础上(而我们的费马小定理不正好满足了要求吗?)

b21 mod pp 为质数 =>p 一定可以被 b1b+1 其中一个整除

这是二次探测定理,原理很简单,我们将上面的同余式左右都减1,根据平方差公式可以得出 (b1)(b+1) 0 mod p 这其实就代表着等式左边是模数的倍数,但若模数p是质数,则 (b1)(b+1) 必定存在一个是 p 的倍数,所以要么 b1=p (b=1) 或者 b+1=p (b=p1) 如果不满足则 p 一定不是质数!然后我们还可以发现若 b=1 我们又可以进行新一轮二次探测!

根据这个道理,我们可以进行二次探测:因为 ap11mod p 如果 p1 为偶数的话就可以化成: a(p12)21 mod p 这样就变成了二次探测的基本式。

typedef long long ll;
typedef unsigned long long ull;
typedef long double lb;
inline ll ksc(ull x, ull y, ll p) {  // O(1)快速乘(防爆long long)
    return (x * y - (ull)((lb)x / p * y) * p + p) % p;
}

inline ll ksm(ll x, ll y, ll p) {  //快速幂
    ll res = 1;
    while (y) {
        if (y & 1) res = ksc(res, x, p);
        x = ksc(x, x, p);
        y >>= 1;
    }
    return res;
}

inline bool mr(ll x, ll p) {
    if (ksm(x, p - 1, p) != 1) return 0;  //费马小定理
    ll y = p - 1, z;
    while (!(y & 1)) {  //一定要是能化成平方的形式
        y >>= 1;
        z = ksm(x, y, p);                    //计算
        if (z != 1 && z != p - 1) return 0;  //不是质数
        if (z == p - 1) return 1;  //一定要为1,才能继续二次探测
    }
    return 1;
}

inline bool prime(ll x) {
    if (x < 2) return 0;
    if (x == 2 || x == 3 || x == 5 || x == 7 || x == 43) return 1;
    return mr(2, x) && mr(3, x) && mr(5, x) && mr(7, x) && mr(43, x);
}

这样子加上二次探测之后,明显就能高效很多,基本上卡不了,大概要每 1010 个数才会出现一个判不掉的,这个概率可以说十分微小,可以忽略!

posted @   RioTian  阅读(1566)  评论(3编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 分享4款.NET开源、免费、实用的商城系统
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
· 5. Nginx 负载均衡配置案例(附有详细截图说明++)
点击右上角即可分享
微信分享提示

📖目录