Miller-Rabin素性判定算法

Miller-Rabin素性判定算法是一种基于概率的判定算法,每次判定n是素数的正确性概率至少为75%,出错的概率小于25%。

如果对n进行k次素性检测,如果结果n为素数,那么n为合数的概率为1/(4^k)。如果k足够大,那么误判的概率就非常小。

算法原理如下:

#include <iostream>
#include <random>
#include <time.h>
using namespace std;
typedef unsigned __int64 llong;//无符号64位整形
//typedef为已有的类型起一个别名。
//既然是别名,对同一类型可以起多个别名。这在C/C++中是允许的,各个别名和真名的作用都是一样有效的。

llong mod_pro(llong x,llong y,llong n)
{
    llong ret=0,tmp=x%n;
    while(y)
    {
        if(y&0x1)
            if((ret+=tmp)>n)
                ret-=n;
        if((tmp<<=1)>n)
            tmp-=n;
        y>>=1;//>>= 意思为:右移后赋值(按位移)
    }
    return ret;

}

//a^b mod c
llong mod(llong a,llong b,llong c)//a:原理中的b,b:m,c:n
{
    llong ret=1;
    while(b)
    {
        if(b&0x1)//b不为偶数
            ret=mod_pro(ret,a,c);//1,随机数,n
        a=mod_pro(a,a,c);
        b>>=1;
    }
    return ret;
}

llong ran()
{
    llong ret =rand();
    return ret*rand();
}

bool is_prime(llong n,int t)//轮数为3
{
    if(n<2)
        return false;
    if(n==2)
        return true;
    if(!(n&0x1))//按位与运算(为偶数)
        return false;
    llong k=0,m,a,i;
    for(m=n-1; !(m&1); m>>=1,k++);// !(m&1):m是偶数
    cout<<m<<" "<<k<<endl;//m是m,k是s:n-1= 2^s*m

    while(t--)
    {
        a=mod(ran()%(n-2)+2,m,n);//ran()%(n-2)+2:随机整数b
        if(a!=1)//圈3
        {
            for(i=0; i<k&&a!=n-1; i++)
            {
                a=mod_pro(a,a,n);
            }
            if(i>=k)
                return false;
        }
    }
    return true;
}

int main()
{

    llong n;
    cout<<"请输入一个大于三的整数:";
    while(scanf("%I64u",&n)!=EOF)//__int64结构的输入格式
    {
        clockid_t starttime,endtime;
        starttime=clock();

        if(is_prime(n,3))
            cout<<"YES\n";
        else
            cout<<"NO\n";
        endtime=clock();
        cout<<"用时"<<endtime-starttime<<"毫秒\n"<<endl;
        cout<<"请输入一个大于三的整数:";
    }
    return 0;
}

学到了:

  • typedef 的用法:typedef为已有的类型起一个别名,同一个类型可以有多个别名,在该例子中把 unsigned __int64 起名为llong 方便引用
  • unsigned __int64 无符号64位整形类型
  • >>= 意思为:右移后赋值(按位移)
  • (n&0x1))//n和十六进制的1按位与运算(为偶数)

原文地址:https://www.cnblogs.com/plumlee/p/12560644.html

时间: 2024-10-04 17:25:20

Miller-Rabin素性判定算法的相关文章

51_1037最长循环节 (miller rabin算法 pollard rho算法 原根)

1037 最长的循环节 V2 基准时间限制:1 秒 空间限制:131072 KB 分值: 320 难度:7级算法题 收藏 关注 正整数k的倒数1/k,写为10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数. 1/6= 0.1(6) 循环节长度为1 1/7= 0.(142857) 循环节长度为6 1/9= 0.(1)  循环节长度为1 Input 输入n(10 <= n <= 10^18) Output 输出<=n的数中倒数循环节长度最长的

Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法

BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1044  Solved: 322[Submit][Status][Discuss] Description Input 第一行:CAS,代表数据组数(不大于350),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数.你需要对于每个数字:第一,检验是否是质数,是质数就输出Prime 第二,如果不是质数,输出它最大的质因子是哪个. O

[算法]Miller Robbin素数判定

Miller Robbin素数判定 一.实现原理 我们以前都是怎么判断素数的呢: inline int is_prime(int n){ if(n==1) return 0; for(int i=2;i<=sqrt(n);i++){ if(n%i==0) return 0; } return 1; } 现在,我们希望更快的判断一个数是否为素数. 我们可以借助费马小定理来判断: 如果p是一个质数,而整数a不是p的倍数,则有 \[a^{p-1}\equiv 1\pmod p\] Miller Rob

MR素性检测算法

转载地址: http://m.blog.csdn.net/blog/spirtsong/38273187 素数是除了自身和1以外,没有其它素数因子的自然数.自从欧几里得证明了有无穷个素数以后,人们就企图寻找一个可以构造所有素数的公式,寻找判定一个自然数是不是素数的方法.因为素数的地位非常重要. 鉴别一个自然数是素数还是合数,这个问题在中世纪就引起人们注意,当时人们试图寻找质数公式,到了高斯时代,基本上确认了简单的质数公式是不存在的,因此,高斯认为对素性判定是一个相当困难的问题.从此以后,这个问题

HDU 3864 D_num Miller Rabin 质数判断+Pollard Rho大整数分解

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3864 题意:给出一个数N(1<=N<10^18),如果N只有四个约数,就输出除1外的三个约数. 思路:大数的质因数分解只能用随机算法Miller Rabin和Pollard_rho,在测试多的情况下正确率是由保证的. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <c

POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】

Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time Limit: 4000MS Description Given a big integer number, you are required to find out whether it's a prime number. Input The first line contains the num

POJ2429_GCD &amp;amp; LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】

GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 Description Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b.

HDU1164_Eddy&amp;#39;s research I【Miller Rabin素数测试】【Pollar Rho整数分解】

Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6664    Accepted Submission(s): 3997 Problem Description Eddy's interest is very extensive, recently he is interested in prime

POJ2429_GCD &amp; LCM Inverse【Miller Rabin素数测试】【Pollar Rho整数分解】

GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 Description Given two positive integers a and b, we can easily calculate the greatest common divisor (GCD) and the least common multiple (LCM) of a and b.