• Miller_Rabin素数测试


     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 long long mul(long long a,long long n,long long mo){
     9     long long ans=0;
    10     while (n){
    11         if (n&1) ans=(ans+a)%mo;
    12         a=(a+a)%mo;
    13         n/=2;
    14     }
    15     return ans;
    16 }
    17 
    18 long long pow(long long a,long long n,long long mo){
    19     long long ans=1;
    20     while (n){
    21         if (n&1) ans=mul(ans,a,mo);
    22         a=mul(a,a,mo);
    23         n/=2;
    24     }
    25     return ans;
    26 }
    27 
    28 bool Miller_Rabin(long long n){
    29     if (n<=2){
    30         if (n==2) return true;
    31         else return false;
    32     }
    33     if (n%2==0) return false;
    34     long long u=n-1;
    35     while (u%2==0){
    36         u/=2;
    37     }
    38     int t=1e2;
    39     while (t--){
    40         long long a=(rand()%(n-2))+2;
    41         long long x=pow(a,u,n);
    42         long long w=u*2;
    43         long long y=mul(x,x,n);
    44         while (w<n){
    45             if (y==1&&x!=1&&x!=(n-1)) return false;
    46             x=y;
    47             y=mul(y,y,n);
    48             w*=2;
    49         }
    50         if (x!=1) return false;
    51     }
    52     return true;
    53 }
    54 
    55 int main(){
    56    int t;
    57    scanf("%d",&t);
    58    while (t--){
    59         long long n;
    60         scanf("%lld",&n);
    61         if (Miller_Rabin(n)) printf("Yes
    ");
    62         else printf("No
    ");
    63    }
    64 
    65 }
    费马小定理:对于质数p和任意整数a,有a^p ≡ a(mod p)(同余)。反之,若满足a^p ≡ a(mod p),p也有很大概率为质数。
    将两边同时约去一个a,则有a^(p-1) ≡ 1(mod p)

    也即是说:假设我们要测试n是否为质数。我们可以随机选取一个数a,然后计算a^(n-1) mod n,如果结果不为1,我们可以100%断定n不是质数。

    否则我们再随机选取一个新的数a进行测试。如此反复多次,如果每次结果都是1,我们就假定n是质数。

    该测试被称为Fermat测试。需要注意的是:Fermat测试不一定是准确的,有可能出现把合数误判为质数的情况。

    Miller和Rabin在Fermat测试上,建立了Miller-Rabin质数测试算法。

    与Fermat测试相比,增加了一个二次探测定理:

    如果p是奇素数,则 x^2 ≡ 1(mod p)的解为 x ≡ 1 或 x ≡ p - 1(mod p)

    如果a^(n-1) ≡ 1 (mod n)成立,Miller-Rabin算法不是立即找另一个a进行测试,而是看n-1是不是偶数。如果n-1是偶数,另u=(n-1)/2,并检查是否满足二次探测定理即a^u ≡ 1 或 a^u ≡ n - 1(mod n)。

    举个Matrix67 Blog上的例子,假设n=341,我们选取的a=2。则第一次测试时,2^340 mod 341=1。由于340是偶数,因此我们检查2^170,得到2^170 mod 341=1,满足二次探测定理。同时由于170还是偶数,因此我们进一步检查2^85 mod 341=32。此时不满足二次探测定理,因此可以判定341不为质数。

  • 相关阅读:
    GFS.BigTable.MapReduce谷歌论文学习笔记
    Android图表
    JAVA内存管理
    关于Ajax工作原理
    走进AngularJs(二) ng模板中常用指令的使用方式
    走进AngularJs(一)angular基本概念的认识与实战
    使用CSS3 制作一个material-design 风格登录界面
    一分钟搞定AlloyTouch图片轮播
    PHP+JQUEY+AJAX实现分页
    全面的Seo面试题
  • 原文地址:https://www.cnblogs.com/pblr/p/6056844.html
Copyright © 2020-2023  润新知