Miller-Rabin
关于Miller-Rabin算法,可以看http://www.matrix67.com/blog/archives/234
主要是用了费马小定理+二次探测,随机选取k个底数进行测试算法的失误率大概为 4−k 。多随机几次就不太容易挂了。
下面代码里的work是用来对拍的根号暴力。
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
namespace runzhe2000
{
typedef long long ll;
bool work(ll x)
{
for(ll i = 2, ii = sqrt(x); i <= ii; i++)
if(x % i == 0) return false;
return true;
}
ll fpow(ll a, int b, ll p)
{
ll r = 1;
for(; b; b>>= 1)
{
if(b & 1) (r *= a) %= p;
(a *= a) %= p;
}
return r;
}
bool MR(ll n)
{
if(n == 2) return 1;
ll a = n-1, b = 0;
for(; !(a&1); a >>= 1, b++);
for(int t = 10; t; t--)
{
ll x = rand()%(n-2)+2, pre;
x = pre = fpow(x, a, n);
for(int i = 0; i < b; i++)
{
(x *= x) %= n;
if(x % n == 1 && pre != 1 && pre != n-1) return false;
pre = x;
}
if(x % n != 1) return false;
}
return true;
}
void main()
{
int n,ans_MR;
for(; scanf("%d",&n) != EOF; )
{
ans_MR = 0;
for(; n--; )
{
ll x; scanf("%lld",&x);
ans_MR += MR(x);
}
printf("%d\n",ans_MR);
}
}
}
int main()
{
runzhe2000::main();
}