前言

在刚接触编程语言时,对于寻找素数,第一时间想到的便是二重循环暴力查找,其复杂度O(n^2),通过循环中只判断到根号n可以优化一些,不过复杂度也达不到预期。在数论的学习中,我学到了埃氏筛法,O(nloglogn)的算法,而在一些数据范围达到1e7这样的题目中,也很难让人满意,于是我便学习了欧拉筛法,也即 O(n)的线性筛法。

埃氏筛法

  • 埃氏筛法的基本思想 :从2开始,将每个质数的倍数都标记成合数,以达到筛选素数的目的。
  • 代码 :
int visit[maxn];
void Prime(){mem(visit,0);           //初始化都是素数visit[0] = visit[1] = 1;  //0 和 1不是素数for (int i = 2; i <= maxn; i++) {if (!visit[i]) {         //如果i是素数,让i的所有倍数都不是素数for (int j = i*i; j <= maxn; j += i) { visit[j] = 1;}}}

这里有一个小优化,j 从 i * i 而不是从 i + i开始,因为 i*(2~ i-1)在 2~i-1时都已经被筛去,所以从i * i开始。

  • 埃氏筛法的缺陷 :对于一个合数,有可能被筛多次。例如 30 = 2 * 15 = 3 * 10 = 5*6……那么如何确保每个合数只被筛选一次呢?我们只要用它的最小质因子来筛选即可,这便是欧拉筛法。

欧拉筛法

  • 欧拉筛法的基本思想 :在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。
  • 代码 :
int prime[maxn];
int visit[maxn];
void Prime(){mem(visit,0);mem(prime, 0);for (int i = 2;i <= maxn; i++) {cout<<" i = "<<i<<endl;if (!visit[i]) {prime[++prime[0]] = i;      //纪录素数, 这个prime[0] 相当于 cnt,用来计数}for (int j = 1; j <=prime[0] && i*prime[j] <= maxn; j++) {
//            cout<<"  j = "<<j<<" prime["<<j<<"]"<<" = "<<prime[j]<<" i*prime[j] = "<<i*prime[j]<<endl;visit[i*prime[j]] = 1;if (i % prime[j] == 0) {break;}}}
}
  1. 对于visit[i*prime[j]] = 1 的解释: 这里不是用i的倍数来消去合数,而是把 prime里面纪录的素数,升序来当做要消去合数的最小素因子。
    打表观察来理解 :

    发现i在消去合数中的作用是当做倍数的。
  2. 对于 i%prime[j] == 0 就break的解释 :当 i是prime[j]的倍数时,i = kprime[j],如果继续运算 j+1,i * prime[j+1] = prime[j] * k prime[j+1],这里prime[j]是最小的素因子,当i = k * prime[j+1]时会重复,所以才跳出循环。
    举个例子 :i = 8 ,j = 1,prime[j] = 2,如果不跳出循环,prime[j+1] = 3,8 * 3 = 2 * 4 * 3 = 2 * 12,在i = 12时会计算。因为欧拉筛法的原理便是通过最小素因子来消除。

结语

对于欧拉筛法的学习是先从接触到题开始的,研究了一天才弄懂,很惭愧,再次遇到题也不见得可以游刃有余的解决,在此与大家共勉,学海无涯。
附上题目 :https://nanti.jisuanke.com/t/30999 (大佬眼中的签到题)

欧拉筛法(线性筛)的学习理解相关推荐

  1. 中高级数论 [欧拉函数线性筛,二次剩余]

    欧拉函数线性筛 对于素数ppp, φ(p∗i)={p−1i=1p∗φ(i)p∣i(p−1)∗φ(i)p∤i\varphi (p*i)= \begin{cases} p-1& i=1\\ p*\ ...

  2. 筛质数—(朴素筛法、埃氏筛法、欧拉筛法(线性筛法))

    筛质数时首先要了解质数的定理:1~n中有  个质数 下面再来看具体算法: 1.朴素筛法: 直接把2~n-1中质数和合数的倍数都筛一遍,其代码如下所示: int primes[N],cnt=0; boo ...

  3. 素数筛法(传统普通、朴素筛法、埃式筛法、欧拉筛法(线性筛))

    素数筛法(普通.朴素筛法.埃式筛法.欧拉筛法) 1.题目 2.分析 3.代码 传统普通 朴素筛法 朴素筛法(6.14) 埃式筛法 埃式筛法(6.14) 欧拉筛法(线性筛) 欧拉筛法(线性筛 6.14) ...

  4. 质数c语言欧拉筛选,Python|欧拉筛法求质数

    欢迎点击「算法与编程之美」↑关注我们! 本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章. 问题描述 我们知道第一个质数是 2.第二个质数是 3.第三个质 ...

  5. 素数计算之埃氏筛法、欧拉筛法

    埃氏筛法 int main() {const int maxNumber=200;int isPrime[maxNumber];int i;int x;for (i=0;i<maxNumber; ...

  6. 埃拉托色尼筛法和欧拉筛法

    筛法 筛法的基本思想是:把从1开始的.某一范围内的正整数从小到大顺序排列, 1不是素数,首先把它筛掉.剩下的数中最小的数是素数,然后去掉它的倍数.依次类推,直到筛子为空时结束. 比如,要产生[2,n] ...

  7. 快速求素数表——埃氏筛法与欧拉筛法

    快速求素数表--埃氏筛法与欧拉筛法 快速求素数表埃氏筛法与欧拉筛法 埃氏筛法 埃氏筛法原理 埃氏筛法时间复杂度 埃氏筛法代码求出1000000以内的素数并且输出n个素数 欧拉筛法 欧拉筛法原理 欧拉筛 ...

  8. UVA516 POJ1365 LA5533 ZOJ1261 Prime Land【欧拉筛法】

    Everybody in the Prime Land is using a prime base number system. In this system, each positive integ ...

  9. UVA12043 Divisors【欧拉筛法】

    Let us define the functions d(n) and σ(n) as d(n)=numberofdivisorsofnd(n) = number of divisors of nd ...

最新文章

  1. Unity shader入门之数据类型
  2. JS常见的几种数组去重方法
  3. chrome使用脚本修改组策略_允许Chrome安装第三方网站的脚本以及扩展的方法
  4. vue.js+flask+element-ui简易Demo 气势的信心
  5. matlab虚拟现实之使用V-Realm Builder2建模
  6. 十、RD 虚拟主机配置(三)
  7. iis出现HTTP 错误 403.14 - Forbidden Web问题
  8. 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
  9. java bartender_BarTender Web Print Server可用的打印方法
  10. SPSS学习笔记:神经网络
  11. Python将多个excel文件合并为一个文件
  12. 电脑 变速 java游戏_极品飞车-变速FX版
  13. SysML精粹学习笔记一
  14. 爬取拉钩网60条招聘信息并存入数据库
  15. 选择时间检定仪应该注意这11点
  16. 0353-如何使用curl命令调用CM的API动态配置Yarn资源池
  17. 大众易融迎“端午”活动公告
  18. QQ空间签到说说表情代码大全
  19. android仿百度地图悬浮式窗口,百度地图(bMap)实现浮动层、按钮等的方法及代码...
  20. 【LeetCode】1710.卡车上的最大单元数

热门文章

  1. 雨水弃流装置详细说明
  2. JD消费者行为分析——漏斗转化
  3. SHT30 温湿度传感器,检验不通过,通讯不稳定(经常读到FF)问题处理
  4. k倍区间(前缀和+组合)
  5. 超简单的 VIM 练级攻略
  6. 1,10-Phen|邻菲啰啉|邻二氮杂菲|1,10-菲啰啉有机配体-66-71-7
  7. Fritzing软件绘制Arduino面包板接线图传感器模块库文件273
  8. GSMA公布2018世界移动大会-上海的最新进展
  9. norflash/nandflash 启动分析 转
  10. MySQL的启动方式