HDU2138 How many prime numbers
题目
Give you a lot of positive integers, just to find out how many prime numbers there are.
输入
There are a lot of cases. In each case, there is an integer N representing the number of integers to find. Each integer won’t exceed 32-bit signed integer, and each of them won’t be less than 2.
输出
For each case, print the number of prime numbers you have found out.
样例输入
3
2 3 4
样例输出
2
题意
给你n个数,求n个数中素数的个数。
分析
使用一般的素数判断也可以,但是这里使用Miller_Rabin算法
C++程序
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
typedef long long ll;
//快速积取模
ll mm(ll a,ll b,ll mod)
{
ll ans=0;
while(b)
{
if(b&1) ans=(ans+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return ans;
}
//快速模取幂
ll f(ll x,ll n,ll mod)
{
ll ans=1;
while(n)
{
if(n&1) ans=ans*x%mod;
x=x*x%mod;
n>>=1;
}
return ans;
}
//Miller-Rabin素数检测算法
bool miller_rabin(ll n)
{
if(n==2)
return true;
else if(n==1||n%2==0)
return false;
ll u=n-1,t=0;
while(u%2==0) u/=2,t++;//n-1=u*2^t
srand(time(NULL));
for(int i=0;i<10;i++)
{
//随机选取一个底数a
ll a=rand()%(n-1)+1;
//计算(a^(n-1))%n=(a^(u*2^t))%n
ll x=f(a,u,n);//先计算(a^u)%n
for(int j=1;j<=t;j++)//再经过t次循环计算得到 ( (a^u)^(2^t) )%n
{
ll y=mm(x,x,n);
//printf("i=%d j=%d y=%d a=%d x=%d\n",i,j,y,a,x);
if(y==1&&x!=1&&x!=n-1)//如果不满足二次探测定理,则不是素数
return false;
x=y;
}
if(x!=1) return false;//如果不满足费马小定理,则不是素数
}
return true;//是素数
}
int main()
{
ll n,x;
while(~scanf("%lld",&n))
{
ll ans=0;
while(n--)
{
scanf("%lld",&x);
ans+=miller_rabin(x);
}
printf("%lld\n",ans);
}
return 0;
}