题意:给出一组数,测试这组数一共有多少个素数
题解:要测试N是否为素数,首先将N-1分解为(2^s)*d。在每次测试开始时,先随机选一个介于[1,N-1]的整数a,如果对所有的r属于[0,s-1]都满足a^dmodN不等于1&&a^((2^r)*d)modN不等于-1,则N是合数,否则,N有3/4的几率为素数。为了提高测试的正确性,可以选择不同的a进行多次测试。
附上代码:
#include<bits/stdc++.h>
using namespace std;
//Miller-Rabin测试
//复杂度O(logn)
typedef long long ll;
ll pow_mod(ll a,ll i,ll n)
{
if(i==0){
return 1%n;
}
ll temp=pow_mod(a,i>>1,n);
temp=temp*temp%n;
if(i&1){
temp=temp*a%n;
}
return temp;
}
bool test(ll n,ll a,ll d)
{
if(n==2){
return true;
}
if(n==a){
return true;
}
if((n&1)==0){
return false;
}
while(!(d&1)){
d=d>>1;
}
ll t=pow_mod(a,d,n);
while((d!=n-1)&&(t!=1)&&(t!=n-1)){
t=(ll)t*t%n;
d=d<<1;
}
return (t==n-1||(d&1)==1);
}
bool isprime(ll n)
{
if(n<2){
return false;
}
int a[]={2,3,61};
for(int i=0;i<=2;i++){
if(!test(n,a[i],n-1)){
return false;
}
}
return true;
}
int main()
{
ll n,temp;
while(scanf("%lld",&n)!=EOF){
ll res=0;
for(int i=0;i<n;i++){
scanf("%lld",&temp);
if(isprime(temp)){
res++;
}
}
printf("%lld\n",res);
}
return 0;
}