模板总结归纳:
#define N 10
typedef long long LL; // 必要时候 unsigned
LL random(LL n)
{
return (LL)((double)rand() / RAND_MAX * n + 0.5);
}
LL multi(LL a, LL b, LL m) //计算a * b % m
{
LL ret = 0;
while(b)
{
if(b & 1) ret = (ret + a) % m;
b >>= 1;
a = (a << 1) % m;
}
return ret;
}
LL quick_mod(LL a, LL b, LL m) //计算a ^ b % m
{
LL ans = 1;
while(b)
{
if(b & 1)
{
ans = multi(ans, a, m);
b--;
}
b >>= 1;
a = multi(a, a, m);
}
return ans;
}
bool miller_rabin(LL n)
{
if(n == 2) return true;
if(n < 2 || !(n & 1)) return false;
LL m = n - 1;
int k = 0;
while((m & 1) == 0)
{
k++;
m >>= 1;
}
for(int i = 0; i < N; i++)
{
LL a = rand() % (n - 1) + 1;
LL x = quick_mod(a, m, n);
LL y = 0;
for(int j = 0; j < k; j++)
{
y=multi(x, x, n);
if(y==1 && x != 1 && x != n - 1) return false;
x = y;
}
if(y != 1) return false;
}
return true;
}
实战模板题 :HDU 2138 How many prime numbers
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;
#define N 10
typedef long long LL; // 必要时候 unsigned
LL random(LL n)
{
return (LL)((double)rand() / RAND_MAX * n + 0.5);
}
LL multi(LL a, LL b, LL m) //计算a * b % m
{
LL ret = 0;
while(b)
{
if(b & 1) ret = (ret + a) % m;
b >>= 1;
a = (a << 1) % m;
}
return ret;
}
LL quick_mod(LL a, LL b, LL m) //计算a ^ b % m
{
LL ans = 1;
while(b)
{
if(b & 1)
{
ans = multi(ans, a, m);
b--;
}
b >>= 1;
a = multi(a, a, m);
}
return ans;
}
bool miller_rabin(LL n)
{
if(n == 2) return true;
if(n < 2 || !(n & 1)) return false;
LL m = n - 1;
int k = 0;
while((m & 1) == 0)
{
k++;
m >>= 1;
}
for(int i = 0; i < N; i++)
{
LL a = rand() % (n - 1) + 1;
LL x = quick_mod(a, m, n);
LL y = 0;
for(int j = 0; j < k; j++)
{
y=multi(x, x, n);
if(y==1 && x != 1 && x != n - 1) return false;
x = y;
}
if(y != 1) return false;
}
return true;
}
int main()
{
LL n, m;
while(cin >> n)
{
LL ans = 0;
while(n--)
{
scanf("%lld", &m);
if(miller_rabin(m)) ans++;
}
cout << ans << endl;
}
return 0;
}
另附一博客:
Miller_Rabin素数测试算法模板对比