[予約] HastinのMiller_Rabin

この記事はで再現されhttps://www.cnblogs.com/zsq259/p/11602175.html

ミラー・ラビン

理由は限られた知識Hastin鶏料理の前の文、食べ物はしたがって、それは特に、言語仕様、唯一の理解ではないかもしれません。

ステップ0

Qの数\(P \)素数かどうか、\(P <= 18} 10 ^ {ある\)

単純なアプローチは、強制することである(O(\ SQRT {N \を \)}) 列挙について。

しかし、明らかに揚げました。

だから我々は、ミラー・ラビンを持っています。

ナンセンスの多くを話します...

ステップ1

まずフェルマーの小定理を見て:

場合\(P \)が素数であり、その後のために([1、で\ \ P-1] \) している\(P A ^ {} \当量A(MOD \) \(P)\)

そこである\(1-P ^ {} \当量。1(MOD \) \(P)\)

ここでは、フェルマーの小定理、それを証明するために数学的帰納法を使用します。

明らかに\(A = 1 \)文が真であるとき、

場合は\(= N \)文は真であるとき、

場合\(= N + 1 \ ) がある場合

\((N + 1)^ P \)\(= \ sum_ I = {0}} ^ {P ^ {C_ {P}} I N-PI ^ {} \)(二項定理)

次に加えて\(N ^ {P} \ ) と\(1 \)外側の2つ、

他は、係数有する(私は\、^ {C_ {P}} I [1、P-1] \)\を、それができる\(P \)割り切れます。

そして\(N-P ^ \ N-当量(MOD \) \(P)\)

そう\((N + 1)^ {P} \ + N-当量1(MOD \) \(P)\) 結論が成り立ちます。

そうトピックに戻る数の、場合\(P \) プレゼンス\(IN A \ [1、P-1] \) \(A ^ {P-は、1} \(MODを\)equiv1ない\ \( P-)\) その後、\(のp \)は確かではない素数。

しかし、検出を逃れることができるいくつかは、まだあります、

だから、

ステップ2

プロービング二次!

素数のための\(P \)であれば、\(で\ [1、P-1] \) および\(A ^ 2 \ equiv1(MOD \) \(P)\) 次いで\(= 1 \)または\(1-P = \)

証明:

もし\(A ^ 2 \ equiv1(MOD \) \(P)\) 次いで\(A ^ 2-1 \当量0(MOD \) \(P)\)

それ\(P |(A + 1)(1-A)\。。)

ので\(P \)は素数であり、([P-1。1]におけるA \ \)\、場合にのみ、そのよう\(= 1 \)または\(= P-1 \ ) 式が成立したときに。

だから、変えたい\(\)は、他の数に等しい、\(P \)は素数ではありません。

ステップ3

ここで再び、特定の実装について話します。

最初の大きなアイデアは、フェルマーの小定理、途中で次のプロービングの判断です。

番号を確認するには、\(のP- \)

セット\(U = P-1 \)は、フェルマーの小定理のに応じて存在する\(A ^ U \当量1(MOD \) \(P)\) \(A \で[1、P-1] \ )

次に\(U \)書かれた\(D * 2 ^ N \ ) 形態、すなわち\((((D ^ 2)^ 2)^ 2)^ 2 {...} \)(N-2番目)

だから、から\(D ^ 2 \)は、第二のプローブを決定することから始まります

最後に、その行にフェルマーの小定理判断。

しかし、時間の複雑さである\(O(LOG_ {\小型2} \) \(P)\)

故障率であった(\ \ FRAC。1 {{}}。4 \)

次に\(T \)誤り率試験である\(4 ^ { - } T \) 時間複雑である(O(TLOG _ {\小型2} Pを)\)\、受け入れることができます。

そしてあれば\(N <2 ^ {64} \) のみを選択\(A = 2、3、 5、7、11、13、17、19、23、29、31、37 \) 試験することができます。

int128を開くように見える:(コード)

#include <iostream>
#include <cstdio>
#include <cstring>
#define int __int128
#define fre(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
using namespace std;

inline int read(){
    int sum=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
    return f*sum;
}

int p[101]={2,3,5,7,11,13,17,19,23,29,31,37};
int T,n,tot=12;

inline int fpow(int a,int b,int p){
    int ret=1;
    for(;b;a=a*a%p,b>>=1) if(b&1) ret=ret*a%p;
    return ret;
}

inline bool Miller_Rabin(int n){
    if(n<=2){
        if(n==2) return 1;
        return 0;       
    }
    int u=n-1;
    while(!(u%2)) u>>=1;
    int d=u;
    for(int i=1;i<tot&&p[i]<n;i++){
        int x=p[i];u=d;x=fpow(x,u,n);       
        while(u<n){
            int y=fpow(x,2,n);
            if(y==1&&x!=1&&x!=n-1) return 0;
            x=y;u<<=1;
        }
        if(x!=1) return 0;
    }
    return 1;
}

signed main(){
    T=read();
    while(T--){
        n=read();
        if(Miller_Rabin(n)) puts("Yes");
        else puts("No");
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/lylyl/p/11668158.html