• 【数学】MillerRabin算法


    原理

    目标:检测某个较大的正整数 (n) 是否为质数。

    证明:

    (n leq 2) 则直接给出结果。否则,若 (n) 为偶数,也直接给出结果。

    否则,假设 (n) 为奇质数,显然 (n-1) 为偶数,可以写成 (2^sd) 的形式,其中 (s) 是正整数,而 (d) 是奇数。则对于任意 (a)(0leq rleq s-1) ,必定满足以下两种形式的一种:

    (a^dequiv 1 pmod{n})(a^{2^rd}equiv -1 pmod{n})

    因为,由于费马小定理,若 (n) 为质数,则 (a^{n-1}equiv 1 pmod{n}) (反之不成立)。

    代码

    ll qmul(ll a, ll b, ll mod) {
        return (__int128)a * b % mod;
    }
    
    ll qpow(ll a, ll b, ll mod) {
        if(a >= mod)
            a %= mod;
        ll res = 1;
        while(b) {
            if(b & 1)
                res = qmul(res, a, mod);
            a = qmul(a, a, mod);
            b >>= 1;
        }
        return res;
    }
    
    namespace MillerRabin {
    
        // private
        bool MR(ll n, ll p) {
            for(ll k = n - 1; k; k >>= 1) {
                ll t = qpow(p, k, n);
                if(t != 1 && t != n - 1)
                    return false;
                if((k & 1) == 1 || t == n - 1)
                    // probably true
                    return true;
            }
            // probably true
            return true;
        }
    
        // public
        bool isPrime(ll n) {
            if(n <= 1)
                return false;
            if(n <= 3)
                return true;
            if(!(n & 1))
                return false;
            static int basePrime[5] = {2, 3, 7, 61, 24251};
            for(int i = 1; i <= 5; ++i) {
                if(n == basePrime[i - 1])
                    return true;
                if(!MR(n, basePrime[i - 1]))
                    return false;
            }
            if(n == 46856248255981LL)
                return false;
            // probably true
            return true;
        }
    
    }
    
    using namespace MillerRabin;
    

    check函数的意图是用质数p作为基检查x是否为质数。

    首先排除掉相等的情况,然后排除掉x已经有p作为质数的情况。然后后续p只会出现在快速幂中,所以先进行一次取模。先用费马小定理确定x不是质数。

  • 相关阅读:
    How to Install Linux, Apache, MySQL, PHP (LAMP) stack on CentOS 6 【Reliable】
    可以把一些常用的方法,写入js文件,引入html界面
    把功能写在方法里,函数化,方法化
    那些SQL语句
    Linux&shell之高级Shell脚本编程-创建菜单
    Linux&shell之高级Shell脚本编程-创建函数
    PHP isset()与empty()的使用区别详解
    如何打开mo文件并修改 PoEdit
    Linux&shell之如何控制脚本
    Linux&shell之显示数据
  • 原文地址:https://www.cnblogs.com/purinliang/p/13676459.html
Copyright © 2020-2023  润新知