Miller–Rabin(米勒拉宾求大素数)

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
using namespace std;
typedef long long ll;

ll mult_mod(ll a,ll b,ll Mod) {     //快乘法,防止快速幂溢出
    ll ans = 0;
    while(b) {
        if(b&1)
            ans = (ans+a)%Mod;
        a = a*2%Mod;
        b >>= 1;
    }
    return ans;
}

ll pow_mod(ll a,ll b,ll Mod) {      //快速幂
    ll ans = 1, base = a;
    while(b) {
        if(b&1)
            ans = mult_mod(ans,base,Mod);
        base = mult_mod(base,base,Mod);
        b >>= 1;
    }
    return ans;
}


ll Pow(ll a,ll b,ll Mod) {
    ll ans = 1,base = a;
    while(b) {
        if(b&1)
            ans = (ans*base)%Mod;
        base = (base*base)%Mod;
        b >>= 1;
    }
    return ans;
}

bool Miller_Rabin(ll n,ll a) {    //米勒拉宾素数测试
    ll d = n-1, s = 0;
    while(!(d&1)) {     //求(2^s)*d中的s和d.
        d >>= 1;
        s ++;
    }
    ll k = pow_mod(a,d,n);

    if(k == 1 )
        return true;

    for(int j=0; j<s; j++) {
        if(k == n-1)
            return true;
        k = mult_mod(k,k,n);    //快乘
    }
    return false;
}

bool IsPrime(ll n) {
    ll a[4] = {3,4,7,11};
    for(int i=0; i<4; i++) {
        if(n == a[i])
            return true;
        if(!n%a[i])
            return false;
        if(n>a[i] && !Miller_Rabin(n,a[i]))
            return false;
    }
    return true;
}


int main() {
    ll n;
    while(~scanf("%lld",&n)) {
        if(n == 2)
            printf("Yes\n");
        else if(n<2 || !(n&1))
            printf("No\n");
        else if(IsPrime(n))
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}


参考博客:https://www.cnblogs.com/JVxie/p/4975876.html
                  http://www.cnblogs.com/jhz033/p/5467919.html

猜你喜欢

转载自blog.csdn.net/qq_16554583/article/details/81032189
今日推荐