标签:
http://acm.hdu.edu.cn/showproblem.php?pid=2138
题意:给n个数判断有几个素数。(每个数<=2^32)
#include <cstdio> using namespace std; typedef long long ll; ll ipow(ll a, ll b, ll m) { ll x=1; for(; b; b>>=1, (a*=a)%=m) if(b&1) (x*=a)%=m; return x; } ll rand(ll a, ll b) { static const ll M=1e9+7, g=460353133; static ll now=1283901ll; return a+((now*=g)%=M)%(b-a+1); } bool check(ll x) { if(x==2 || x==3 || x==5 || x==7 || x==11 || x==13) return 1; if(x<2 || (x&1)==0 || (x%3)==0 || (x%5)==0 || (x%7)==0 || (x%11)==0 || (x%13)==0) return 0; int cnt=0; ll d=x-1; while((d&1)==0) d>>=1, ++cnt; for(int T=1; T<=50; ++T) { int a=rand(2, x-1); ll t=ipow(a, d, x), pre; for(int i=1; i<=cnt; ++i) { pre=t; (t*=t)%=x; if(t==1 && pre!=1 && pre!=x-1) return 0; } if(t!=1) return 0; } return 1; } int main() { int n; while(~scanf("%d", &n)) { int ans=0; for(int i=1; i<=n; ++i) { int a; scanf("%d", &a); if(check(a)) ++ans; } printf("%d\n", ans); } return 0; }
学习了素数检测= =Miller-Rabin...
其实基于两个定理:费马小定理和二次探测...
首先如果$n$是奇素数,那么显然对于所有的$1 \le a < n$,都有$a^(n-1) \equiv 1 \pmod{n}$,那么我们马上可以得到一个暴力算法= =(比枚举约数还慢系列= =
然后用那啥二次探测定理然后随机选一些$a$然后一定概率来检测$n$= =(听说单次检测是$3/4$的概率= =那么多次检测成功率很高= =$n$次的能检测出来的概率就是$\sum_{i=0}^{n} \binom{n}{i} (\frac{3}{4} )^i (\frac{1}{4})^{n-i}$
二项探测就是指如果$n$是素数,则$x^2 \equiv 1 \pmod{n}, 0<=x<n$的只有就是$x = 1 或 x = n-1$
证明:容易得到$p | (x+1)(x-1)$。而由于$p$是质数,所以$(x+1)$和$(x-1)$中至少一个被$p$整除。那么容易得到$x = \pm 1$,即$x \equiv 1 或 x \equiv n-1$
【HDU】2138 How many prime numbers
标签:
原文地址:http://www.cnblogs.com/iwtwiioi/p/4353427.html