题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2138
Miller-Rabin(链接)模板题
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define ll long long
ll Mod_t(ll n,ll& t)//获得n的u* 2^t =n的u的值
{
t=0;
while((n&1)==0)
{
t++;
n>>=1;
}
return n;
}
ll Mod_u(ll a,ll u,ll n)//利用快速幂求出a^u的值
{
ll base=a;
ll sum=1;
while(u)
{
if(u&1) sum=sum*base%n;
base = base*base%n;
u>>=1;
}
return sum;
}
bool Miller_Rabin(int n)//利用Miller_Rabin判断n是否为素数
{
if(n==2) return true;
if(n<2||(n&1)==0) return false;
ll t,a;
ll y;
ll x;
ll u=Mod_t(n-1,t);//求出n-1=u * 2^t 中的u,与t的值
for(int i=0;i<10;i++) //这里表示用几次a^u,次数越多准确度越高
{
a=rand()%(n-1) + 1;
x=Mod_u(a, u, n);//求出a^u mod n的值
for(int j=0;j<t;j++)
{
y=(x*x)%n;
if(y==1&& x!=1 && x!=n-1)
return false;
x=y;
}
if(x!= 1 ) return false ; //经过t次后x=a^(n-1) mod n, (费马小定理)若x不为1,说明n一定不为素数
}
return true;
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
ll m,n,x,y;
ll cnt=0;
ll z;
while(~scanf("%lld", &n)){
cnt=0;
while(n--)
{
scanf("%lld",&z);
if(Miller_Rabin(z))
cnt++;
}
printf("%lld\n",cnt);
}
return 0;
}