首先,在了解米勒-拉宾素性测试之前,我们要先了解费马小定理。
关于费马小定理就不再细说原理和证明了,应用非常广泛。
费马小定理中说 若p是质数 则有 a的(p-1)次方在(mod p)的情况下 恒等于1 数学表达式---> a^(p-1) ≡ 1 (mod p)
然后我们要注意: p若是质数 则满足费马小定理 但是 满足费马小定理 并不能证明p就是质数
有些数字 满足费马小定理,但是并不是质数 他们叫做伪质数(伪素数的个数是无穷的)
那么 知道了这些 算法就很好理解了
一个数 如果满足费马小定理 那么他很大几率就是素数了 但是还有可能不是
米勒-拉宾素性测试就是 令费马小定理中的a 分别等于多个数 然后拿每一个a去测试 n 若所有的测试 都满足费马小定理 那么n就是素数
通过快速幂 我们可以很快的检测是否满足费马小定理
在一定范围内 伪素数是有限的 只要选区恰当的a的值 呢们就可以保证这是一个确定性的算法 下面详细给出a的选择
if n < 1 373 653 a = 2 and 3.
if n < 9 080 191 a = 31 and 73.
if n < 4 759 123 141 a = 2, 7, and 61. 和longint是一个数量级
if n < 2 152 302 898 747 a = 2, 3, 5, 7, and 11.
模板题hdu2138 链接 http://acm.hdu.edu.cn/showproblem.php?pid=2138
代码
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; ll mod; ll mul(ll a,ll b){//高精度 a%=mod; b%=mod; ll c=(long double)a*b/mod; ll ans=a*b-c*mod; return (ans%mod+mod)%mod; } ll pow_mod(ll x,ll n){//快速幂 ll res=1; while(n){ if(n&1) res=mul(res,x); x=mul(x,x); n>>=1; } return res; } bool Miller_Rabbin(ll x){ if(x==2)return true; if(x%2==0)return false; mod=x; if(pow_mod(2,x-1)==1&&pow_mod(7,x-1)==1&&pow_mod(61,x-1)==1){ return true; } return false; } ll n,x; int main(){ while(~scanf("%lld",&n)){ int cnt=0; for(int i=0;i<n;i++){ scanf("%lld",&x); if(Miller_Rabbin(x)) cnt++; } printf("%d\n",cnt); } return 0; }
原文地址:https://www.cnblogs.com/precious-ZPF/p/9481599.html
时间: 2024-10-11 18:52:20