判断是否为素数

bool IsPrime(int n)
{
	if (n == 1) return false;
	if (n == 2 || n == 3) return true;
	if (n % 6 != 1 && n % 6 != 5)return false;
		
	int len = sqrt(n);
	for (int i = 5; i <= len; i += 6)
	{
		if (n % i == 0 || n % (i + 2) == 0)
			return false;
	}
	return true;
}
unsigned mod_pow(unsigned a, unsigned b, unsigned mod) {
    unsigned result = 1;
 
    while (b > 0) {
        if (b & 1)
            result = unsigned(uint64_t(result) * a % mod);
 
        a = unsigned(uint64_t(a) * a % mod);
        b >>= 1;
    }
 
    return result;
}
 
bool miller_rabin(unsigned n) {
    if (n < 2)
        return false;
 
    // Check small primes.
    for (unsigned p : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29})
        if (n % p == 0)
            return n == p;
 
    int r = __builtin_ctz(n - 1);
    unsigned d = (n - 1) >> r;
 
    for (unsigned a : {2, 7, 61}) {
        unsigned x = mod_pow(a % n, d, n);
 
        if (x <= 1 || x == n - 1)
            continue;
 
        for (int i = 0; i < r - 1 && x != n - 1; i++)
            x = unsigned(uint64_t(x) * x % n);
 
        if (x != n - 1)
            return false;
    }
 
    return true;
}
class Miller_Rabin{
public:
	/*
	对于2的32以内的判素,选取2,7,61 三个底数即可。
	对于小于2的64以内的判素,选取2,325,9375,28178,450775,9780504,1795265022 七个底数即可。
	如果是考场上,选取2,3,5,7,11,13,17,19,23,29,31,37(也就是前十二个质数)作为底数即可,它适用于2的78以内的判素。
	*/
	typedef long long int ll;
	Miller_Rabin(){
		prime = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 };
	}
	ll mod_pow(ll a, ll p, ll mod){
		ll ret = 1;
		while (p){
			if (p & 1) ret = ret * a % mod;
			a = a * a % mod;
			p >>= 1;
		}
		return ret;
	}
	inline bool chk(ll mod, ll a, ll b, ll x)
	{
		ll v = mod_pow(x, a, mod);
		if (v == 1) return 1;
		int j = 1;
		while (j <= b)
		{
			if (v == mod - 1) break;
			v = v * v % mod;
			j++;
		}

		return j <= b;
	}
	bool check(ll n){
		if (n > 37){
			ll a = n - 1, b = 0;
			while (a & 1) a >>= 1, b++;
			for (int i = 0; i < prime.size(); i++) {
				if (!chk(n, a, b, prime[i])) return false;
			}
		}
		else{
			for (int i = 0; i < prime.size(); i++){
				if (prime[i] == n) return true;
			}
			return false;
		}

		return true;
	}
private:
	vector<int> prime;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值