为了测试一个大整数是不是素数,我们不能够使用传统的测试是否有因子的方法,因为那样的时间复杂度至少也是O(n)O(n)O(n),空间复杂度是O(n)O(n)O(n)(使用线性筛数法),时间复杂度还好说,空间复杂度在n比较大的时候完全不可以接受,这就需要我们使用Miller_RabinMiller\_RabinMiller_Rabin算法进行解决。

算法的核心使用了费马小定理和二次探测定理

费马小定理:若ppp为质数,则ap−1≡1(modp)a^{p-1}\equiv 1\pmod pap−1≡1(modp)

这是一个质数的必要条件,但是有一类特殊的数也满足这个等式并且是合数(卡米歇尔数),为了剔除这些特殊的数,我们还需要二次探测定理帮助判断

二次探测定理:如果ppp为素数,x2≡1(modp)x^2\equiv 1 \pmod px2≡1(modp),则x=1或x=p−1x=1 或 x=p-1x=1或x=p−1

因此对于满足费马小定理的数ppp,即ap−122≡1(modp){a^{\frac{p-1}{2}}}^2\equiv 1\pmod pa2p−1​2≡1(modp),我们判断ap−12a^{\frac{p-1}{2}}a2p−1​是否为1或者p−1p-1p−1,如果不是说明ppp不是素数,如果是我们可以继续对ap−12a^{\frac{p-1}{2}}a2p−1​进行探测

每一次检测都无法100%确定这是一个素数,但是判断8次几乎不可能出错。

这里的mult函数是乘积函数,因为接近long long 的数字相乘会爆long long,这里按位相乘。

在研究的很多人的实现后我实现了以下,觉得我这个复杂度低一些(因为自己写的缘故看起来很亲切)。实际过题时间也比之前看到的快。

typedef long long ll;
ll mult(ll x,ll y,ll p)
{long double d=1; d=d*x/p*y;return ((x*y-((ll)d)*p)%p+p)%p;
}ll quick_pow(ll a,ll b,ll p)
{a%=p; ll ret=1;while(b){if(b&1) ret=mult(ret,a,p);a=mult(a,a,p); b>>=1;}return ret;
}bool Miller_Rabin(ll n)
{if(n<2) return false;const int times=8;const ll prime[times]={2,3,5,7,11,13,17,61};for(int i=0;i<times;i++)if(n==prime[i]) return true;else if(n%prime[i]==0) return false;ll x=n-1; while(~x&1) x>>=1;for(int i=0;i<times;i++){ll a=prime[i]; ll now=quick_pow(a,x,n); ll last;if(x==n-1){if(now!=1) return false;}else{while(x!=n-1){x<<=1; last=now; now=mult(now,now,n);if(now==1){if(last!=1 && last!=n-1) return false;break;}}}}return true;
}

之前看到的别人的板子

ll mult(ll a, ll b, ll p) {a %= p;b %= p;ll res = 0, tmp = a;while(b) {if (b & 1) {res += tmp;if (res > p) res -= p;}tmp <<= 1;if (tmp > p) tmp -= p;b >>= 1;}return res;
}ll quick_pow(ll a, ll b, ll p) {ll res = 1;ll tmp = a % p;while(b) {if (b & 1) res = mult(res, tmp, p);tmp = mult(tmp, tmp, p);b >>= 1;}return res;
}bool check(ll a, ll n, ll x, ll t) {ll res = quick_pow(a, x, n);ll last = res;for (ll i = 1; i <= t; i++) {res = mult(res, res, n);if (res == 1 && last != 1 && last != n-1) return true;last = res;}return res != 1;
}bool Miller_Rabin(ll n) {if (n < 2) return false;if (n == 2) return true;if ((n & 1) == 0) return false;ll x = n-1;ll t = 0;while ((x & 1) == 0) {x >>= 1;t++;}srand(time(NULL));const ll tims = 8;for (ll i = 0; i < tims; i++) {ll a = rand() % (n-1) + 1;if (check(a, n, x, t)) return false;}return true;
}

Miller_Rabin算法相关推荐

  1. Pollard_rho算法+Miller_Rabin算法(大素数的判断与素因子分解)(模板)

    const int S=20;//随机算法判定次数,S越大,判错概率越小 //计算 (a*b)%c. a,b都是long long的数,直接相乘可能溢出的 // a,b,c <2^63 LL m ...

  2. c语言 快速筛质数,快速筛素数(埃式筛+线性筛+Miller_Rabin算法)

    在CF上做到一道核心是需要筛出1~n所有素数的题目,然后刚好又没学过,就学习了快速筛素数的办法,基础的n根号n的算法这里大家每个人都知道吧QAQ,就不讲了,好像还是C语言上机说过的题目. 首先给大家介 ...

  3. hdu 4910 Problem about GCD 找规律+Miller_Rabin算法+线性筛

    题意: 输入一个正整数n(n<=1e18),输出所有的i相乘并对n取余所得的值.(gcd(i,n)==1,1<=i<=n) 题解: 比赛的时候花了一个小时找规律,楞是没找到,无语死了 ...

  4. BZOJ 4802: 欧拉函数(大数因数分解算法 Pollard_rho 和素数测试算法 Miller_Rabin)

    Description 已知N,求phi(N) Input 正整数N.N<=10^18 Output 输出phi(N) Sample Input 8 Sample Output 4 Soluti ...

  5. 素数判定算法 MILLER RABIN

    入门级筛素数--试除法,复杂度O(n^2) bool rmprime( long long n ) {for(long long i = 2; i <= sqrt(n) ; i++) if(n% ...

  6. HDU2138 随机素数测试 Miller-Rabin算法

    题目描述 Give you a lot of positive integers, just to find out how many prime numbers there are.. In eac ...

  7. c语言中int下小数求余大数,Sicily1020-大数求余算法及优化

    Github最终优化代码: https://github.com/laiy/Datastructure-Algorithm/blob/master/sicily/1020.c 题目如下: 1020. ...

  8. python实现shamir秘密共享算法

    shamir算法介绍 拉格朗日插值解密 代码实现 用到的G_hash是国密算法SM3, g_p是Miller_Rabin算法生成大素数算法 ModReverse是生成逆元算法 from random ...

  9. Miller_Rabbin算法判断大素数,Pollard_rho算法进行质因素分解

    Miller-rabin算法是一个用来快速判断一个正整数是否为素数的算法.它利用了费马小定理,即:如果p是质数,且a,p互质,那么a^(p-1) mod p恒等于1.也就是对于所有小于p的正整数a来说 ...

最新文章

  1. [力扣] 二叉树的层序遍历
  2. JAVA JDK+Eclipse IDE for Java Developers下载
  3. 阿里面试题Linux curl命令详解
  4. 超级签名源码_苹果iOS超级签名源码技术解析
  5. C语言在STM32中的内存分配
  6. 计算机或与非门原理,依据基本原理构建现代计算机:从与非门到俄罗斯方块(基于项目的课程)...
  7. 对比罗小平先生的《delphi精要》和李维先生的《inside VCL》
  8. 活动选择问题 贪心
  9. T-SQL DATEPART() Functions
  10. SLAM之PTAM学习笔记
  11. 建筑企业收并购系列二:吸收合并政策影响
  12. 华硕天选如何改变屏幕亮度,以及键盘灯的效果
  13. 分析 | 多视角下图情热点分析与真题分析
  14. 文件夹加密专家 v2.6 免费
  15. curl_exec函数
  16. 转]60个英文阅读网站强力推荐
  17. NLP基础模型和注意力机制
  18. iOS6.1完美越狱工具evasi0n1.3下载
  19. Evernote导出pdf windows
  20. Python匿名函数的使用lambda

热门文章

  1. eclipse安装java web插件
  2. Java开发人员的升级之路
  3. canvas 图片反色
  4. 32位系统win2008+mssql2008 6G内存折腾纪实
  5. GridView 利用AspNetPager 分页时的自动编号
  6. Together与Visual.Studio.NET的结合使用(三)
  7. mac安装了多版本php 卸载,mac 安装多版本PHP
  8. java map clone_Java中HashMap的clone()方法: java.util.HashMap.clone() - Break易站
  9. mysql怎么按年份分组_mysql - MYSQL按ID分组,但根据最近的年份进行拉取 - SO中文参考 - www.soinside.com...
  10. php安装dat,PHP Parsing a .dat file