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}$$
  • 相关阅读:
    【leetcode】字符串轮转
    【leetcode】URL化
    【leetcode】学生出勤记录 I
    【leetcode】子域名访问计数
    【leetcode】整数的各位积和之差
    【leetcode】另一个树的子树
    【leetcode】查询后的偶数和
    【leetcode】左叶子之和
    【leetcode】从根到叶的二进制数之和
    【leetcode】平方数之和
  • 原文地址:https://www.cnblogs.com/zjjws/p/14157450.html
Copyright © 2011-2022 走看看