zoukankan      html  css  js  c++  java
  • Miller Rabin

    概要

    一种随机化判定质数方法。

    根据执行次数不断增加,其正确率可以快速增长,以达到我们想要的目的。


    前置知识

    二次探测定理

    对于质数 (p),若有 (a^2equiv 1pmod p),那么 (aequiv pm 1pmod p)

    证明:

    [a^2-1equiv 0pmod p ]

    [(a+1)(a-1)equiv 0pmod p ]

    因为 (p) 是质数,由唯一分解可得:

    [aequiv pm 1 ]


    算法流程

    (p-1) 拆分成 (2^k imes t) 的形式,然后 随机 rand 一个 (a),计算出 (a^t)

    每次比较 (a^{2^i imes t}pmod p)(a^{2^{i+1} imes t}pmod p,iin[0,k)) 是否符合前文的二次探测定理。

    若出现了一项不符合,即可判定 (p) 为合数。

    那么对于当前 rand 出来的这个 (a),有 一定的概率 可以判断出来 (p) 是合数(如果是的话)。

    经过一次 (p) 不是质数却未被判出的概率似乎最大为 (frac{1}{4}),具体的我也算不来。

    那么做个七八次就好了,非常的稳妥。

    可以用 (2,3,5,7,11,13,17,19) 这几个质数作为 (a),也可以 rand 几个质数,看个人习惯。


    代码实现

    主要是调用的函数部分。

    bool pri[20];
    vector<int>prime;
    inline void init()
    {
        for(int i=2;i<20;i++){if(!pri[i])prime.push_back(i);for(auto j:prime){int now=i*j;if(now>=20)break;pri[now]=true;if(i%j==0)break;}}
        pri[1]=true;srand(time(0));return;
    }
    inline bool Miller_Robin(LL n,int a)
    {
        LL t=n-1,lst;int k=0;for(;!(t&1);t>>=1)k++;lst=t=ksm(a,t,n);
        for(int i=1;i<=k;i++){t=prpr(t,t,n);if(t==1&&lst!=1&&lst!=n-1)return false;lst=t;}return lst==1;
    }
    inline bool ifprime(LL n){if(n<20)return !pri[n];for(auto j:prime)if(!Miller_Robin(n,j))return false;return true;}
    
    
    $$ exttt{Dirty Deeds Done Dirt Cheap}$$
  • 相关阅读:
    思念
    空白
    curl json string with variable All In One
    virtual scroll list All In One
    corejs & RegExp error All In One
    socket.io All In One
    vue camelCase vs PascalCase vs kebabcase All In One
    element ui 表单校验,非必填字段校验 All In One
    github 定时任务 UTC 时间不准确 bug All In One
    input range & color picker All In One
  • 原文地址:https://www.cnblogs.com/zjjws/p/14157450.html
Copyright © 2011-2022 走看看