zoukankan      html  css  js  c++  java
  • 米勒拉宾素数检测

    是一种随机化素数检测算法

    基于下面的定理

    • 费马小定理:如果p是素数,a不是p的倍数,那么(a ^ {p - 1} equiv 1(mod p))
    • 二次探测定理:如果p是一个素数,且x∈[1,p - 1],则方程(x ^2 \% p = 1)的解为(x = 1)(x = p - 1)

    费马小定理的逆命题:如果(a^{p - 1} equiv 1(mod p))成立,那么p是一个素数且a不是p的倍数

    可以确定费马小定理的逆命题不一定成立。

    那么对于一个数,如果不满足(a ^ {p - 1} equiv 1(mod p))那么一定不是素数,如果满足,那么有可能是素数,取a = [1,p)的随机数,在进行判断,进行几次即可,则为素数的可能性越大

    但是对于卡迈克尔数,(卡迈克尔数是一个合数p,a不是p的倍数,但符合a^{p - 1}equiv 1(mod p))

    则需要每次判断费马小定理时,进行二次探测,排除卡迈克尔数

    算法

    当p为2时为素数

    当p小于2或偶数时不是素数

    10次检测,随机化(a∈[1,p))求出(a^u \% n),然后二次探测判断

    其中进行优化,使得进行二次探测时的幂小一点,然后在慢慢扩大,不然,如果直接计算p - 1次幂,可能会造成溢出的情况

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #define ll long long
    using namespace std;
    ll mod_mul(ll a,ll b,ll p){//a * b % p
        ll ans = 0;
        while(b){
            if(b & 1)ans = (ans + a) % p;
            b >>= 1;
            a = (a + a) % p;
        }
        return ans;
    }
    ll mod_exp(ll a,ll b,ll p){
        ll ans = 1;
        while(b){
            if(b & 1)ans = mod_mul(ans,a,p);//a和b可能很大
            b >>= 1;
            a = mod_mul(a,a,p);
        }
        return ans;
    }
    bool miller_rabin(ll n){
        if(n == 2)return 1;
        if(n < 2 || !(n & 1))return 0;
        ll u,t;
        for(t = 0,u = n - 1; !(u & 1); t++,u>>=1);//n-1 =u*2^t
        for(int i = 0; i < 10; i++){//10次试探
            ll a = rand() % (n - 1) + 1;//a∈[1,n)
            ll x = mod_exp(a,u,n);
            for(int j = 0; j < t; j++){//二次试探
                ll y = mod_mul(x,x,n);
                if(y == 1 && x != 1 && x != n - 1)
                    return 0;
                x = y;//相当于把幂变回到p - 1
            }
            if(x != 1)return 0;
        }
        return 1;
    }
    int main(){
        srand(time(NULL));
        int n;
        scanf("%d",&n);
        printf("%s
    ",miller_rabin(n)?"YES":"NO");
        return 0;
    }
    
  • 相关阅读:
    今天入住博客园,希望有个好的开始,自己在这边可以学习成长
    浅谈 C# ref 和 out 的使用方法
    类之间的几种关系
    VB6.0 文件日志读取
    基于NPOI的Excel导入和导出功能
    WebService的创建,发布与调用
    C# OfType 的使用
    Vb6.0 文件日志记录
    ZipInputStream
    [转载]遗传算法入门
  • 原文地址:https://www.cnblogs.com/Emcikem/p/12321496.html
Copyright © 2011-2022 走看看