zoukankan      html  css  js  c++  java
  • Miller-Rabin 素数检验算法

    算法简介

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

    费马小定理判质数

    (a^{p - 1} ≡ 1 mod p)

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

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

    二次探测定理

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

    (b^2≡1 mod p)(p) 为质数 (=>)(p) 一定可以被 (b−1)(b+1) 其中一个整除

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

    根据这个道理,我们可以进行二次探测:因为 (a^{p−1}≡1mod p) 如果 (p−1) 为偶数的话就可以化成: (a^{(frac{p−1}2)^2}≡1 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);
    }
    

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

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    火车进出站(POJ1363)
    字符串反转,栈模拟(ZOJ1151)
    模拟网页的浏览Stack(POJ1028)
    Codeforces Round #347 (Div.2)_B. Rebus
    Codeforces Round #347 (Div.2)_A. Complicated GCD
    BFS模板
    广搜破解密码(HDU1195)
    DFS+BFS(POJ3083)
    砍树,POJ(2665)
    快速幂取模,POJ(1995)
  • 原文地址:https://www.cnblogs.com/RioTian/p/13927952.html
Copyright © 2011-2022 走看看