【模板】Miller-Rabin素數測試
阿新 • • 發佈:2018-12-17
參考題目:HDU2138
解析:
又是一個看心情更新的板子題。。。
程式碼:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline ll getint(){
re ll num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while (isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return num;
}
inline ll mul(ll a,ll b,ll mod){
return (a*b-(ll)((long double)a/mod*b)*mod+mod)%mod;
}
inline ll quickpow(ll a,ll b,ll mod){
re ll ans=1;
for(;b;b>>=1,a=mul(a,a,mod))if(b&1)ans=mul(ans,a,mod);
return ans;
}
cs int P=10000007;
bitset<P> mark;
int prime[P],pcnt;
inline void linear_sieves(int len=P-7){
mark[1]=true;
for(int re i=2;i<=len;++i){
if(!mark[i])prime[++pcnt]=i;
for(int re j=1;j<=pcnt&&i*prime[j]<=len;++j){
mark[i*prime[j]]=true;
if (i%prime[j]==0)break;
}
}
}
inline bool isprime(ll x){
if(x<=P-7)return !mark[x];
if(!(x&1)||(x%3==0)||(x%5==0)||(x%7)==0)return false;
ll t=x-1,s=0;
while(!(t&1))t>>=1,++s;
for(int re i=1;i<=14&&prime[i]<x;++i){
ll num=quickpow(prime[i],t,x),pre=num;
if(x%prime[i]==0)return false;
for(int re j=0;j<s;++j){
num=mul(num,num,x);
if(num==1&&pre!=1&&pre!=x-1)return false;
pre=num;
}
if(num!=1)return false;
}
return true;
}
int n;
signed main(){
linear_sieves();
while(~scanf("%d",&n)){
int ans=0;
while(n--)if(isprime(getint()))++ans;
printf("%d\n",ans);
}
return 0;
}