Miller-Rabin判素模板(板子总结)

思路来源

https://blog.csdn.net/Originum/article/details/81303853

代码

如果WA,可以在不TLE情况下,适当加T的次数

还有个O(1)的快速乘的方法

ll mul(ll u,ll v,ll p)
{
return (u*v-ll((long double)u*v/p)*p+p)%p;
}
#include 
#include 
using namespace std;
 
typedef long long  ll;
const int T = 9;

ll mod_mult(ll a, ll b, ll mod) {           //大数乘法取模
    a %= mod;
    b %= mod;
    ll ans = 0;
    while (b) {
        if (b & 1) {
            ans += a;
            if (ans >= mod)
                ans -= mod;
        }
        a <<= 1;
        if (a >= mod) a = a - mod;
        b >>= 1;
    }
    return ans;
}
 
ll mod_pow(ll x, ll n, ll mod) {            //快速幂
    if (n == 0) return 1;
    ll res = mod_pow(mod_mult(x , x , mod), n / 2, mod);
    if (n & 1) res = mod_mult(res , x , mod);
    return res;
}
 
 
bool check(ll a, ll n, ll x, ll t) {       //来判断是不是素数
    ll ret = mod_pow(a, x, n), last = ret;
    for (int i = 1; i <= t; i ++) {
        ret = mod_mult(ret, ret, n);
        if (ret == 1 && last != 1 && last != n - 1) return true;//合数
        last = ret;
    }
    if (ret != 1) return true;
    else return false;
}
 
bool Miller_Rabin(ll n)         //Miller_Rabin算法
{
    if( n < 2) return false;
    if( n == 2) return true;
    if(!(n & 1)) return false;//偶数
    ll x = n - 1, t = 0;
    while (!(x & 1)) { x >>= 1; t++;}
    for (int i = 0; i < T; i ++) {
        ll a = rand() % (n - 1) + 1;
        if (check(a, n, x, t))
            return false;
    }
    return true;
}

 

你可能感兴趣的:(知识点总结)