入门级筛素数--试除法,复杂度O(n^2)

bool rmprime( long long n )
{for(long long i = 2; i <= sqrt(n) ; i++)    if(n%i == 0) return false;return true;
}

学了一段时间算法以后,应该会了解到筛法求素数,复杂度略高于O(n)

#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 500000;
bool isp[MAXN];
int p[MAXN];
int cnt = 0;//保存素数个数
void getp()
{for(int i = 1; i < MAXN; i++)    isp[i] = 1 ; //默认全部素数for(int i = 2; i < MAXN; i++){if(!isp[i]) continue; //如果不是素数就continue掉p[cnt++] = i;for(int j = i * 2 ; j < MX; j += i)        isp[j] = 0;//记录,往后滚处理
    }
}int main(){getp();for(int i = 0; i < cnt; i++)    printf("%d ",p[i]);return 0;
}

当然,不难发现,如果MaX值过大的话,不只空间会炸,而且从头开始扫很玄学,是不怎么可取的。

于是引入MILLER RABIN算法。可以单独判断一个大数是否素数,但是不保证正确。我们只能通过多次执行算法让这个错误的概率很小。//不过幸运的是,除非你是非酋王,这个算法一般都是不会出问题的。

算法的理论基础:
1. Fermat定理:若n是奇素数,a是任意正整数(1≤ a≤ n−1),则 a^(n-1) ≡ 1 mod n。
2. 推演自Fermat定理(具体过程我没看懂,Orz), 如果n是一个奇素数,将n−1表示成2^s*r的形式,r是奇数,a与n是互素的任何随机整数,那么a^r ≡ 1 mod n或者对某个j (0 ≤ j≤ s−1, j∈Z) 等式a^(2jr) ≡ −1 mod n 成立。
聪明的读者已经发现上述的定理是一个数是素数的必要条件而非充分条件,所以这就是这个算法的不精确的原有,对于一些特定的检验算子a,存在一些合数也满足上述定理。所以我们要多找几个a反复检验,这样能让错误率大大降低。
那么我们按照上述的定理2,首先重复n次实验。对于每一次实验,随机取检验算子a,带入定理2进行检验,看看在算子a下,n能否满足
a^r ≡ 1 mod n或者对某个j (0 ≤ j≤ s−1, j∈Z) 等式a^(2jr) ≡ −1 mod n       **
如果任意一次实验不满足,则判定不是素数,如果都满足,可近似可以认为是素数(错误率极小)。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
using namespace std;const int times = 20;
int number = 0;map<long long, int>m;
long long Random( long long n )            //生成[ 0 , n ]的随机数
{return ((double)rand( ) / RAND_MAX*n + 0.5);
}long long q_mul( long long a, long long b, long long mod ) //快速计算 (a*b) % mod
{long long ans = 0;while(b){if(b & 1){b--;ans =(ans+ a)%mod;}b /= 2;a = (a + a) % mod;}return ans;
}long long q_pow( long long a, long long b, long long mod ) //快速计算 (a^b) % mod
{long long ans = 1;while(b){if(b & 1){ans = q_mul( ans, a, mod );}b /= 2;a = q_mul( a, a, mod );}return ans;
}bool witness( long long a, long long n )//miller_rabin算法的精华
{//用检验算子a来检验n是不是素数long long tem = n - 1;int j = 0;while(tem % 2 == 0){tem /= 2;j++;}//将n-1拆分为a^r * slong long x = q_pow( a, tem, n ); //得到a^r mod nif(x == 1 || x == n - 1) return true;    //余数为1则为素数while(j--) //否则试验条件2看是否有满足的 j
    {x = q_mul( x, x, n );if(x == n - 1) return true;}return false;
}bool miller_rabin( long long n )  //检验n是否是素数
{if(n == 2)return true;if(n < 2 || n % 2 == 0)return false;                //如果是2则是素数,如果<2或者是>2的偶数则不是素数for(int i = 1; i <= times; i++)  //做times次随机检验
    {long long a = Random( n - 2 ) + 1; //得到随机检验算子 aif(!witness( a, n ))                        //用a检验n是否是素数return false;}return true;
}int main( )
{long long tar;while(cin >> tar){if(miller_rabin( tar ))    //检验tar是不是素数cout << "Yes, Prime!" << endl;elsecout << "No, not prime.." << endl;}return 0;
}

转载于:https://www.cnblogs.com/shuri/p/7638588.html

素数判定算法 MILLER RABIN相关推荐

  1. 与数论的厮守01:素数的测试——Miller Rabin

    看一个数是否为质数,我们通常会用那个O(√N)的算法来做,那个算法叫试除法.然而当这个数非常大的时候,这个高增长率的时间复杂度就不够这个数跑了. 为了解决这个问题,我们先来看看费马小定理:若n为素数, ...

  2. 你知道如何判定一个大整数为素数吗?——米勒拉宾素数判定算法

    米勒拉宾算法的基本概念如下: 首先判断这个数n的奇偶性 若为偶数仅有2是质数 奇数则进入测试 测试方法: 首先确定几个基底a,范围在[2,n-1] 因为n是奇数,所以n-1必定为偶数 则n-1可以表示 ...

  3. 费马小定理与素数判定

    费马小定理是初等数论四大定理(威尔逊定理,欧拉定理(数论中的欧拉定理,即欧拉函数),中国剩余定理和费马小定理)之一,在初等数论中有着非常广泛和重要的应用.实际上,它是欧拉定理的一个特殊情况. 其内容为 ...

  4. 经典加密算法的实现与破解大素数生成算法

    0x00 信息系统安全实验报告 实验(一):经典加密算法的实现与破解 1. 实现凯撒加密.暴力破解凯撒加密 2. 选取k值,编译凯撒加密算法 3. 编写算法尝试暴力破解凯撒加密 实验(二):大素数生成 ...

  5. 素数判定 Miller-Rabin 算法的实现 python

    素数判定 Miller-Rabin 算法的实现 实验目的 通过实验掌握 Miller-Rabin 素数判定的算法. 实验原理 Miller-Rabin primality test | encyclo ...

  6. (Miller Rabin算法)判断一个数是否为素数

    (Miller Rabin算法)判断一个数是否为素数 1.约定 x%y为x取模y,即x除以y所得的余数,当x<y时,x%y=x,所有取模的运算对象都为整数. x^y表示x的y次方.乘方运算的优先 ...

  7. 素数判定质因数分解(数论)(Miller Rabin)(Pollard Rho)

    太玄学了! 我真的被概率的魅力折服了.此前我认为1便是1,0.9999999999-便是0.9999999999-. 但实际上它们有着千丝万缕的关系. 试想,如果一件事发生的概率是0.99999999 ...

  8. Magic的Miller Rabin素数测定和Pollard's Rho质因子分解法

    boshi大佬帮助了litble,使愚蠢的litble(可能?)学会了这种神奇的算法. orz boshi. 例题:poj1811 Miller Rabin 又称米勒挝饼, 一种神奇的快速判定一个数是 ...

  9. ECPP——利用有限域上的椭圆曲线,精确判定素数的算法

    要说明的是,现在这篇东西是研究用椭圆曲线精确判定一个正整数是否为素数,而不是研究用椭圆曲线加解密的! 当然,后面提供的一些关于有限域上的椭圆曲线上的点的加法,乘法,除法的实装函数都是可以直接用于加解密 ...

最新文章

  1. iOS 开发者账号 到期续费问题
  2. C 语言 静态库和动态库的创建和应用
  3. Facebook解释“宕机”原因:主干路由器配置变化致通信中断,未发现用户数据受影响...
  4. Adnroid提高效率之资源移动
  5. JAVA ulimit,java-从linux中的jvm中查找硬打开和软打开文件限制(ulimit -n和ulimit -Hn)
  6. 在vue项目中同时使用element-ui和mint-ui,的时候,.babelrc配置文件怎么写
  7. 数学笔记(四)线性代数知识点总结
  8. 项目Beta冲刺(7/7)(追光的人)(2019.5.29)
  9. 大众点评各城市热门餐厅评分字体加密信息数据采集
  10. 阿里云心选“小眯眼摄像头”视频监控天猫精灵可控手机远程wifi高清
  11. Android内存泄漏总结,一线互联网公司面经总结
  12. 为什么总是闹离职的员工没走,平时不吭声的员工却突然离职?
  13. matlab 复数函数拟合,Matlab中实验数据【复数】的曲线拟合
  14. 如何让手机1秒打开健康码?
  15. oracle 百分位数,Oracle分析函数PERCENTILE_CONT
  16. Centos8.3 nfs-ganesha使用ceph后端
  17. 【面向对象】Java面向对象内容
  18. 【阿里巴巴百川掌中测 限量内测招募啦】来自阿里的移动开发测试洪荒之力
  19. 奇文|意识如何演化?机器何时有自我意识?《附着与隧通-心智的工作模式》
  20. Element:Table表格在单元格内放多个数据

热门文章

  1. NDK error Error 126 make: *** Deleting file
  2. 谷歌推出了其首款触屏笔记本电脑
  3. 已经导入依赖,但是Cannot resolve symbol“registerFunction“
  4. AuthFailed at /social-auth/complete/facebook/
  5. linux安装x11鼠标主题
  6. NFL discussion调研
  7. Kaggle Kernels和 Colab, Binder, Azure Notebooks, CoCalc, Datalore的比较
  8. fatal error: Python.h: 没有那个文件或目录 解决方法
  9. windows下面sublime无法粘贴复制的问题解决(转)
  10. sublime的TAB和空格统一