费马定理的逆定理几乎可以用来判断一个数是否为素数,但是有一些数是判断不出来的,因此,Miller_Rabin测试方法对费马的测试过程做了改进,克服其存在的问题。

推理过程如下(摘自维基百科):

摘自另一篇博文(手动滑稽):

原理明白了,就直接上代码了(KuangBin大神的板子):

代码思路是,

  • Miller_Rabin()函数随机选取 s 个a,a用做“基底”
  • check() 函数是用来判断x是否等于1,也就是判断a是否是n的凭证。
  • Mul_mod()函数是 快速乘 ,求 a^t % n 之后的值是否为正负一,因为两个数直接乘的话会很大,可能会爆Long Long, 因此用快速乘边乘边mod。
  • pow_mod()函数是 快速幂 ,在刚开始第一次判断 a^(n-1) % n 时会用到。
 /* *************************************************
* Miller_Rabin 算法进行素数测试
* 速度快可以判断一个 < 2^63 的数是不是素数
*
**************************************************/
const int S = ; //随机算法判定次数一般 8 ∼ 10 就够了
// 计算 ret = (a*b)%c
//a,b,c < 2^63
long long mult_mod(long long a,long long b,long long c)
{
a %= c;
b %= c;
long long ret = ;
long long tmp = a;
while(b)
{
if(b & )
{
ret += tmp;
if(ret > c)ret -= c;//直接取模慢很多
}
tmp <<= ;
if(tmp > c)tmp -= c;
b >>= ;
}
return ret;
}
// 计算 ret = (a^n)%mod
long long pow_mod(long long a,long long n,long long mod)
{
long long ret = ;
long long temp = a%mod;
while(n)
{
if(n & )ret = mult_mod(ret,temp,mod);
temp = mult_mod(temp,temp,mod);
n >>= ;
}
return ret;
}
// 通过 a^(n − 1)=1(mod n)来判断 n 是不是素数
// n − 1 = x ∗ 2 t 中间使用二次判断
// 是合数返回 true, 不一定是合数返回 false
bool check(long long a,long long n,long long x,long long t)
{
long long ret = pow_mod(a,x,n);
long long last = ret;
for(int i = ; i <= t; i++)
{
ret = mult_mod(ret,ret,n);
if(ret == && last != && last != n - )return true;//合数
last = ret;
}
if(ret != )return true;
else return false;
}
//**************************************************
// Miller_Rabin 算法
// 是素数返回 true,(可能是伪素数)
// 不是素数返回 false
//**************************************************
bool Miller_Rabin(long long n)
{
if( n < )return false;
if( n == )return true;
if( (n&) == )return false;//偶数
long long x = n - ;
long long t = ;
while( (x&)== )
{
x >>= ;
t++;
}
srand(time(NULL));/* *************** */
for(int i = ; i < S; i++)
{
long long a = rand()%(n - ) + ;
if( check(a,n,x,t) )
return false;
}
return true;
}

Miller_Rabin 素数测试的更多相关文章

  1. 数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test

    Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 29046   Accepted: 7342 Case ...

  2. hdu 6169 Senior PanⅡ Miller_Rabin素数测试+容斥

    Senior PanⅡ Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Pr ...

  3. Miller_Rabin素数测试【学习笔记】

    引语:在数论中,对于素数的研究一直就很多,素数测试的方法也是非常多,如埃式筛法,6N±1法,或者直接暴力判(试除法).但是如果要判断比较大的数是否为素数,那么传统的试除法和筛法都不再适用.所以我们需要 ...

  4. Miller_Rabin素数测试

    #include<iostream> #include<cmath> #include<cstdio> #include<cstring> #inclu ...

  5. 数学:随机素数测试(Miller_Rabin算法)和求整数素因子(Pollard_rho算法)

    POJ1811 给一个大数,判断是否是素数,如果不是素数,打印出它的最小质因数 随机素数测试(Miller_Rabin算法) 求整数素因子(Pollard_rho算法) 科技题 #include< ...

  6. Miiler-Robin素数测试与Pollard-Rho大数分解法

    板题 Miiler-Robin素数测试 目前已知分解质因数以及检测质数确定性方法就只能\(sqrt{n}\)试除 但是我们可以基于大量测试的随机算法而有大把握说明一个数是质数 Miler-Robin素 ...

  7. Miller-Rabin素数测试算法(POJ1811Prime Test)

    题目链接:http://poj.org/problem?id=1811 题目解析:2<=n<2^54,如果n是素数直接输出,否则求N的最小质因数. 求大整数最小质因数的算法没看懂,不打算看 ...

  8. poj 1811 Prime Test 大数素数测试+大数因子分解

    Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 27129   Accepted: 6713 Case ...

  9. Miller-Rabbin随机性素数测试算法

    //**************************************************************** // Miller_Rabin 算法进行素数测试 //速度快,而且 ...

随机推荐

  1. kaggle 欺诈信用卡预测——Smote+LR

    from:https://zhuanlan.zhihu.com/p/30461746 本项目需解决的问题 本项目通过利用信用卡的历史交易数据,进行机器学习,构建信用卡反欺诈预测模型,提前发现客户信用卡 ...

  2. [T-ARA][결혼 하지마][不要结婚]

    歌词来源:http://music.163.com/#/song?id=27808773 作曲 : 二段横踢 [作曲 : 二段横踢] 作词 : 二段横踢 [作词 : 二段横踢] Hey anybody ...

  3. PAT甲题题解-1044. Shopping in Mars (25)-水题

    n,m然后给出n个数让你求所有存在的区间[l,r],使得a[l]~a[r]的和为m并且按l的大小顺序输出对应区间.如果不存在和为m的区间段,则输出a[l]~a[r]-m最小的区间段方案. 如果两层fo ...

  4. 20135220谈愈敏Linux Book_1&2

    第一章 Linux内核简介 从unix的历史视角来认识Linux内核与Linux操作系统的前世今生. Unix历史 贝尔实验室设计的一个文件系统原型逐渐演化而成Unix,而后Unix操作系统用C语言重 ...

  5. (Alpha)Let's-Chronos分数分配规则

    Requirement: 每个团队开一个讨论会,协商讨论团队贡献分的分配方式.每个团队的团队贡献分为50分/人.每个人分数不能相同,请详细说明分数的分配规则. 为了完成此次的团队贡献分的分配任务,我们 ...

  6. ElasticSearch 2 (36) - 信息聚合系列之显著项

    ElasticSearch 2 (36) - 信息聚合系列之显著项 摘要 significant_terms(SigTerms)聚合与其他聚合都不相同.目前为止我们看到的所有聚合在本质上都是简单的数学 ...

  7. 《当大数据遇见网络:大数据与SDN》

    总体结构: <当大数据遇见网络:大数据与SDN> 摘要 大数据和SDN无论是对于学术界还是工业界来说都极具吸引力.传统上人们都是分别在最前沿工作中研究这两个重要的领域.然而一方面,SDN的 ...

  8. final版本发布评价II

    其实我对技术上的问题了解不多,所以有些评语可能说的不对或者压根就没啥用.可直接忽略.请见谅. 1新蜂的俄罗斯方块,UI设计虽然给出了背景和颜色,但是感觉色彩对比也不好,模块之间也不协调.没有更多的说服 ...

  9. Ubuntu18.04 安装后的简单实用设置[未完成]

    1. 安装完成. 2. 更新 sudo apt-get update 3. 修改vi 放置键盘错位的问题 编辑文件/etc/vim/vimrc.tiny 将“compatible”改成“nocompa ...

  10. 改善C++ 程序的150个建议学习之建议7:时刻提防内存溢出

    作为一个程序员,对内存溢出问题肯定不陌生,它已经是软件开发历史上存在了近40年的大难题.在内存空间中,当要表示的数据超出了计算机为该数据分配的空 间范围时,就产生了溢出,而溢出的多余数据则可以作为指令 ...