普通的素数判断法
当我们要判断一个数字是否是素数的时候,往往会直接看这个数字模1到这个数字的根号,看有没有等于零的,从而判断这个数字是不是素数,这样做的时间复杂度为O(sqrt(n))

bool isPrime(int num)
{if(num <= 1)return false;for(int i = 2; i * i <= num; ++i){if(num % i == 0)return false;}return true;
}

线性筛法求素数
线性筛法,时间复杂度为O(n)
原理在这里:https://blog.csdn.net/bjrxyz/article/details/8125913

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 2e5 + 5;
ll prime[maxn];
ll cnt = 0;
bool not_prime[maxn] = {1, 1};//0 和 1不是素数
void init()
{for(ll i = 2; i < maxn; ++i){if(!not_prime[i])prime[cnt++] = i;for(ll j = 0; j < cnt && i * prime[j] < n; ++j){not_prime[i * prime[j]] = 1;if(!(i % prime[j]))break;}}
}
int main()
{init();return 0;
}

二次筛法求素数[L,R]
当我们的素数很大很大,但区间跨度不大时。

bool Prime[50010];      //存50000内素数判断结果
int Primer[1000010];    //存放区间[L,R]之间的素数
bool Prime1[1000010];   //判断区间[L,R]中的数是否为素数
int IsPrime()//第一次筛50000内的素数
{int num = 0;for(int i = 2; i <= 50000; i++)Prime[i] = true;for(int i = 2; i <= 50000; i++){if(Prime[i]){Primer[num++] = i;for(int j = i+i; j <= 50000; j+=i)Prime[j] = false;}}return num;     //num为50000范围内的素数个数
}
int IsPrime2(__int64 a,__int64 b)
/*
在第一次筛素数的基础上,利用50000以内的素数,筛去范围【a,b】之间的素数倍数,
剩下则为素数
*/
{int num = IsPrime();memset(Prime1,true,sizeof(Prime1));//Prime1数组用来存放范围【a,b】的素性判断if(a == 1)  //这里注意1不是素数Prime1[0] = 0; //这里表示0+1不为素数for(__int64 i = 0; i < num && Primer[i] * Primer[i] <= b; i++){__int64 begin = a/Primer[i] + (a%Primer[i] != 0);//上边的a/Primer算出应a为素数Primer[i]的多少倍//(a%Primer[i]!=0)表示应从Primer[i]的a/Primer[i]倍开始筛,还是a/Primer[i]+1倍筛if(begin == 1)//若得出结果为所被筛素数的1倍,则从该素数的2倍开始筛begin++;for(begin = begin*Primer[i]; begin <= b; begin += Primer[i])Prime1[begin - a] = false;}//这里重新利用Primer数组,用来存放区间【a,b】间的素数,num为素数个数memset(Primer,0,sizeof(Primer));num = 0;for(__int64 i = a; i <= b; i++)if(Prime1[i-a]==1)Primer[num++] = i-a;return num;     //num为区间[a,b]的素数个数
}

米勒拉宾素性检验
如果区间跨度很大,例如在1e14到1e18,用筛法求素数时数组开不了那么大。
所以我们改用米勒拉宾算法对素数进行检验。米勒拉宾素性测试算法是概率算法,不是确定算法。但是判断错误的概率非常非常小,速度又很快。

#include<iostream>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
bool Miller_Rabin(long long n)
{if(n < 2)return false;else if(n == 2)return true;long long q = 0, m = n - 1;while(m % 2 == 0) {   //当m为偶数时m >>= 1;//除2++q;   //计数}long long a = rand()%(n - 2) + 2;long long x1 = (long long)pow(a, m) % n, x2;for(int i = 1; i <= q; ++i) {x2 = (x1 * x1) % n;if(x2 == 1 && x1 != 1 && x1 != n - 1)return false;x1 = x2;}if(x2 != 1)return false;elsereturn true;
}
int main(void)
{srand((unsigned)time(NULL));long long num;while(cin >> num) {if(num > 1) {if(Miller_Rabin(num))cout << "true" << endl;elsecout << "false" << endl;}}return 0;
}
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
LL mulmod( LL a, LL b , LL p )
{LL  d = 1;a = a % p;while( b > 0 ){if(b & 1)d = (d * a) % p;a = (a * a) % p;b >>= 1;}return d;
}
bool witness( LL a,LL n)
{LL d = n - 1 ;if( n == 2 )return true ;if( !(n & 1) ) return false ;while(!(d & 1)) d = d / 2;LL t = mulmod(a, d, n);while((d != n - 1) && (t != 1) && (t != n - 1)){t = mulmod( t, 2, n);d = d << 1;}return (t == n - 1) || (d & 1);
}
bool isprime( LL n)
{int a[3] = {2, 7, 61};for(int i = 0; i < 3; i++)if(!witness(a[i], n))return false;return true;
}
int main()
{LL s;cin >> s;if(isprime(s))cout << "YES";elsecout << "NO";return 0;
}

参考来源

博客
https://blog.csdn.net/lianai911/article/details/45056957
博客
https://blog.csdn.net/bjrxyz/article/details/8125913
博客
https://www.cnblogs.com/KyleDeng/p/9244850.html

数论 判断素数:普通素数判别 线性筛 二次筛法求素数 米勒拉宾素数检验相关推荐

  1. C++实现伪大素数生成算法(费马小定理判别法、米勒拉宾素数判定法)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一.伪大素数生成原理 方法一 方法二 数学基础 二.费马小定理判别法 1.算法 2.代码实现 3.运行结果 二.米勒拉宾素数 ...

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

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

  3. 2018宁夏网络赛 B Goldbach (米勒拉宾素数测试)

    2018宁夏网络赛 B Goldbach (米勒拉宾素数测试) 题目链接 题目大意: 给你一个偶数n (2<n<=1e18) 让你把n分解成两个素数的和.(如果有多个输出任意一个) 解题思 ...

  4. 题目 1084: 用筛法求之N内的素数(数论)

    文章目录 Question Ideas Code Question 题目描述 用筛法求之N内的素数. 输入 N 输出 0-N的素数 样例输入 100 样例输出 2 3 5 7 11 13 17 19 ...

  5. 普通素数 筛法求素数 二次筛法求素数 MillerRabin素数测试【模板】

    素数和合数共同的性质: 1.a > 1是合数,当且仅当a = b * c,其中1 < b < a,1 < c < a. 2.合数必有素数因子. 3.如果d > 1, ...

  6. ACMNO.17C语言-筛法求素数 用筛法求之N内的素数。

    题目描述 用筛法求之N内的素数. 输入 N 输出 0-N的素数 样例输入 100 样例输出 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 7 ...

  7. 母牛python_《Python》 母牛的故事Hello, world用筛法求之N内的素数

    1:题目: 有一头母牛,它每年年初生一头小母牛.每头小母牛从第四个年头开始,每年年初也生一头小母牛.请编程实现在第n年的时候,共有多少头母牛? def f(n): f1,f2,f3=1,2,3 if ...

  8. 用筛法求之N内的素数

    用筛法求之N内的素数. 时间限制: 1 Sec  内存限制: 64 MB 提交: 127  解决: 105 [提交][状态][讨论版][Edit] [TestData] 题目描述 用筛法求之N内的素数 ...

  9. 蓝桥杯每日一练——用筛法求之N内的素数 python

    题目描述 用筛法求之N内的素数. 输入 N 输出 0-N的素数 样例输入 100 样例输出 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 7 ...

最新文章

  1. Windows Internals 笔记——错误处理
  2. 死磕单点登录的实现原理
  3. python 比较列表相邻元素(找相同或去重)
  4. 一步步使用SAP CRM Application Enhancement Tool创建扩展字段
  5. android 如何 root权限获取,如何获取android手机root权限获取
  6. ps图片如何实现渐变
  7. linux操作系统学习心得
  8. log4j 日志输出级别
  9. mysql alter字段_mysql alter语句添加、修改、删除字段的例子
  10. python自动注册邮箱_Python自动登录126邮箱的方法
  11. python使用Speech_Recognition实现普通话识别(一)
  12. 实时性是指计算机多媒体系统中声音及活动,《计算机应用基础》电子教案
  13. 【光通信】Wi-Fi联盟——Wi-Fi 7与Wi-Fi 6相比到底有哪些变化
  14. Myabtis源码分析五-Mybatis配置加载完全图解,建造者模式的使用,涵盖Java各种技术栈
  15. SVA介绍-----断言基础
  16. 问题:The ABAP program lines are wider than the internal table.
  17. kindle取消注册与注册教程
  18. Rufus 制作 USB 启动盘简单教程
  19. win10鼎信诺为什么安装不了_win10 企业版系统 office2007办公软件 鼎信诺数据导不出来 为什么呢|鼎信诺如何导出excle底稿...
  20. 每天学一个 Linux 命令(113):dnf

热门文章

  1. Vue判断IE浏览器版本并提示
  2. pycharm设置文件模板
  3. uVision, MDK, realview的关系
  4. 沃尔沃推出纯电动汽车Polestar 2 续航里程和Model 3接近
  5. 埃森哲《2022 中国企业数字化转型指数》: 中国企业数字化进程五年间稳步推进,17% 企业成领军者
  6. 微信小程序:小秋工具箱开发总结
  7. 音频/面板资源管理器_AudioPanelManager
  8. MyBatis 学习(七):深入 Mapper XML映射文件
  9. [安卓开发] Broadcast 三种广播的使用总结
  10. VTM1.0代码阅读:CU、PU、TU