判斷是否是素數
long long power(long long v, long long p, long long m)
{
long long r = 1;
while(p)
{
if(p & 1) r = r * v % m;
v = v * v % m;
p >>= 1;
}
return r;
}
bool witness(long long a, long long p)
{
int k = 0;
long long q = p - 1;
while((q & 1) == 0)
++k, q >>= 1;
long long v = power(a, q, p);
if(v == 1 || v == p - 1)
return false;
while(k-- != 0)
{
v = v * v % p;
if(v == p - 1)
return false;
}
return true;
}
bool miller_rabin(long long p)
{
if(p == 2) return true;
if(p % 2 == 0) return false;
for(int i = 0; i != 50; ++i)
{
long long a = std::rand() % (p - 1) + 1;
if(witness(a, p))
return false;
}
return true;
}
證實能ac的板子:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <ctime>
using namespace std;
#define random(a, b) (rand()%(b-a+1)+a) //取得在[a,b]間的隨機數
typedef long long ll;
typedef long double ld;
ll mul(ll a, ll b, ll MOD) //快速乘法
{
return (a * b - (ll)((ld)a / MOD * b) * MOD + MOD) % MOD;
}
ll mod_pow(ll x, ll n, ll mod)//快速冪
{
ll ans = 1;
while(n > 0)
{
if(n & 1)
ans = mul(ans, x, mod);
x = mul(x, x, mod);
n >>= 1;
}
return ans;
}
bool is_prime(ll n)
{
if(n == 2)
return true;
else if(n % 2 == 0)
return false;
srand((unsigned)time(NULL));
for(int i = 1; i <= 1000; i++)
{
ll a = random(1, n-1); //取得在[1,n-1]的隨機數
if(mod_pow(a, n-1, n) != 1)
return false;
}
return true;
}