Miller-Rabin 素性测试学习笔记
Miller-Rabin 素性测试二次学习笔记
首先把 \(p=2\) 和 \(2|p\) 判了。
首先我们知道费马小定理:
但这反过来时不对的,即若
我们可以不断的尝试 \(a\) 看是否满足使得 \(n\) 满足费马小定理,当对于足够多的 \(a\) ,费马小定理都成立时,我们认为 \(n\in \mathbb P\)。
但是有一些合数 \(n\),称作"Carmichael数(卡迈克尔数)",满足 \(\forall a\bot n,a^{n-1}\equiv 1\pmod n\),比如 \(n=561\)。这使得上述的方法一定产生误判,我们应该排除这些数的影响。
二次素性测试
引理:假设 \(p\) 是奇素数,那么 \(x^2\equiv1\pmod p\implies x\equiv \pm1\pmod p\)
证明显然。
假设 \(n-1=d\times 2^s,2\nmid d\),那么 \(p\) 是质数的必要条件是:
\(\forall 0\le i<s\),若 \(a^{2^{i+1}d}\equiv 1\pmod p\),则必须有 \(a^{2^id}\equiv \pm 1\pmod p\)。
这样就可以排除卡迈克尔数了。
可行性证明
分析可得,合数 \(n\) 是 Carmichael 数当且仅当 \(n\) 无平方因子且对 \(n\)! 的任意质因子 \(p\) 均有 \(p-1|n-1\)。设 \(n=p_1p_2p_3\cdots q_1q_2q_3\cdots\)
根据中国剩余定理,\(\bmod n\) 意义下一定存在且仅存在唯一一个 \(a\),使得:
这样
所以 \(a^d\not\equiv \pm 1\pmod n,a^{2d}\equiv 1\mod n\)。
这与二次素性探测的必要条件不符,因此所有 Carmichael 数都可以被测出来。
确定化算法
当 \(n\le 2^{64}\) 时,将 \(a\) 取遍前 \(12\) 个质数 \(2,3,5,7,11,13,17,19,23,29,31,37\) 即可全部判断出来。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int p[12]={2,3,5,7,11,13,17,19,23,29,31,37};
int QP(int a,int b,int p){
    int c=1%p;
    for(;b;b>>=1){
        if(b&1)c=(__int128)c*a%p;
        a=(__int128)a*a%p;
    }
    return c;
}
bool Test(int a,int n){
    if(QP(a,n-1,n)!=1)return false;
    int d=n-1,s=0;
    while(!(d&1))s++,d>>=1;
    for(int i=0,nxt=QP(a,d,n),now=1;i<s;i++){
        now=nxt,nxt=(__int128)nxt*nxt%n;
        if(nxt==1&&now!=1&&now!=n-1)return false;
    }
    return true;
}
bool Miller_Rabin(int n){
    if(n<2)return false;
    if(n==2)return true;
    if(n%2==0)return false;
    for(int i=0;i<12;i++){
        if(n%p[i]==0)continue;//注意互质的条件 
        if(!Test(p[i],n))return false;
    }
    return true;
}
signed main(){
    cin>>n;
Miller_Rabin(n);
    return 0;
}

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号