Miller_rabin板子 快速判断是否素数

板子,除了这个算法不保证一定正确,效率很高,错误率很低可以忽略不记

如果用这个板子出现了wa而不是tle的时候,可以适当增加_time的次数

const int _time=5;
ll multi(ll a, ll b, ll mod) {
    ll ret = 0;
    while(b) {
        if(b & 1) ret = ret + a;
        if(ret >= mod) ret -= mod;
        a = a + a;
        if(a >= mod) a -= mod;
        b >>= 1;
    }
    return ret;
}
ll quick_pow(ll a, ll b, ll mod) {
    ll ret = 1;
    while(b) {
        if(b & 1) ret = multi(ret, a, mod);
        a = multi(a, a, mod);
        b >>= 1;
    }
    return ret;
}
bool Miller_Rabin(ll n) {
    ll u = n - 1, pre, x;
    int i, j, k = 0;
    if(n == 2 || n == 3 || n == 5 || n == 7 || n  == 11) return true;
    if(n == 1 || (!(n % 2)) || (!(n % 3)) || (!(n % 5)) || (!(n % 7)) || (!(n % 11)))
        return false;
    for(; !(u & 1); k++, u >>= 1);
    srand(time(NULL));
    for(i = 0; i < _time; i++) {
        x = rand() % (n - 2) + 2;
        x = quick_pow(x, u, n);
        pre = x;
        for(j = 0; j < k; j++) {
            x = multi(x, x, n);
            if(x == 1 && pre != 1 && pre != (n - 1))
                return false;
            pre = x;
        }
        if(x != 1) return false;
    }
    return true;
}

 

你可能感兴趣的:(模板)