你好|

ASnown

园龄:2年6个月粉丝:13关注:15

Miller-Rabin 素性测试算法

前提

Miller-Rabin 素性测试算法需要如下两个引理:

1. 费马小定理

p 是素数,a 为整数,且 (a,p)=1,则 ap11(modp)

证明:

 1,2,3,,(p1)  p1  a  a,2a,3a,,(p1)aab(modp),(c,p)=1acbc(modp)1×2××(p1)a×2a××(p1)a(modp)(p1)!(p1)! ×ap1(modp)((p1),p)=1ap11(modp)

2. 二次探测定理

p 是一个素数,且 0<x<p,则方程 x21(modp) 的解为 x=1p1
证明:

 x210(modp)(x+1)(x1)0(modp)p|(x+1)(x1)p x=1  x=p1

算法介绍

首先,费马小定理只是判定 p 为质数的必要条件。即费马小定理不成立,n 一定是合数;费马小定理成立,n 也有可能不是质数。

下面来看 Miller-Rabin 算法的分析过程:

假设 n 为素数且 n>2,则 n1 为偶数。令 n1=2qm

随机选取整数 a(0<a<n)

由费马小定理可得 (a2qm=an1)1(modn)

再由二次探测定理可得 a2q1m1(modn)a2q1mn1(modn)

a2q1m1(modn) 成立,那么再由二次探测定理可得 a2q2m1(modn)a2q2mn1(modn)……

反复使用二次探测定理拆解,直到拆解到 am1(modn)amn1(modn)

总结一下:am1(modn) 或存在 0r<q 使得 a2rmn1(modn),则称 n 通过 Miller 测试。

但是还存在一种伪素数,它们可以通过 Miller 测试但却不是素数。

但是经过证明 Miller-Rabin 算法的错误率小于等于 14。若用不同的素数作为 a 测验 k 次,错误率可降低至 4k

这里还有一个小技巧。如果被测数小于 4759123141 那么只需要测试 3 个底数 2,7,61即可。当然,你测试的越多,范围也就越大。如果你用前7个素数(2,3,5,7,11,13,17)测试,不超过 341550071728320 都是正确的。如果你选用2,3,7,61,24251作为底数,那么 1016 内唯一的伪素数是 46856248255981,是 4840261 的倍数。对于 OIer 来说,已经非常够用了。

Code

当然,对于身为OIer的我们来说,代码肯定是最重要的。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Test[5] = {2,3,7,61,24251};
int tsped(int a,int b,int m){
    int ans=0;
    for(;b;b>>=1,(a<<=1)%=m)
        if(b&1)(ans+=a)%=m;
    return ans;
}
int qpow(int a,int b,int m){
    int ans=1;
    for(;b;b>>=1,a=tsped(a,a,m))
        if(b&1)ans=tsped(ans,a,m);
    return ans;
}
bool Miller_Rabin(int n){
    if(n==2)return true;
    if(n<2||!(n&1))return false;
    if(!(n%4840261))return false;
    int m=n-1,q=0;
    while(!(m&1))q++,m>>=1;
    for(int i=0;i<5;i++){
        if(Test[i]==n)continue;
        int a=qpow(Test[i],m,n),b;
        for(int j=1;j<=q;j++){
            b=tsped(a,a,n);
            if(b==1&&a!=1&&a!=n-1)
                return false;
            a=b;
        }
        if(b!=1)return false;
    }
    return true;
}
signed main(){
    int n;
    cin>>n;
    while(n--){
        int a;
        cin>>a;
        cout<<Miller_Rabin(a)<<endl;
    }
    return 0;
}

本文作者:ASnown

本文链接:https://www.cnblogs.com/As-Snow/p/16938849.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   ASnown  阅读(184)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起