思路:Miller-Rabin测试
代码如下:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<ctime>
using namespace std;
typedef long long ll;
const int N=50;
ll random(ll n){
return (ll)((double)rand()/RAND_MAX*n+0.5);
}
ll multi(ll a,ll b,ll m){
return a*b%m;
}
ll quick_mod(ll a,ll b,ll m)
{
ll ans=1;
while(b){
if(b&1){
ans=multi(ans,a,m);
}
b>>=1;
a=multi(a,a,m);
}
return ans;
}
bool Witness(long long a,ll n)
{
ll m=n-1;
int j=0;
while(!(m&1))
{
j++;
m>>=1;
}
ll x=quick_mod(a,m,n);
if(x==1||x==n-1)return false;
while(j--)
{
x=x*x%n;
if(x==n-1)return false;
}
return true;
}
bool miller_rabin(ll n){
if(n<2)return false;
if(n==2)return true;
if(!(n&1))return false;
for(int i=1;i<=N;++i){
ll a=random(n-2)+1;
if(quick_mod(a,n-1,n)!=1)return false;
// if(Witness(a,n))return false;//(二次探测定理,两个随便一个都能过这道题)
}
return true;
}
int main(){
// freopen("data.txt","r",stdin);
srand(time(NULL));
int n;
while(scanf("%d",&n)!=EOF){
int ans=0;
ll a;
while(n--){
scanf("%I64d",&a);
if(miller_rabin(a))ans++;
}
printf("%d\n",ans);
}
return 0;
}