1. 程式人生 > >【模板】Miller-Rabin素數測試

【模板】Miller-Rabin素數測試

參考題目: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; }