埃拉托色尼素数筛法(转)
原文:http://blog.csdn.net/ltyqljhwcm/article/details/52835805
1.算法原理
首先:
1 for(int i=2;i*i<N;i++) 2 { 3 if(d%i==0) break; 4 }
导入:
1 memset(prime,1,sizeof(prime)); //初始假设所有的数都是素数 2 3 prime[0]=prime[1]=0; //初始确认0,1不是 4 for(int i=2;i*i<N;i++) 5 { 6 if(prime[i]) 7 { 8 for(int j=2;i*j<N;j++) prime[i*j]=0; 9 } 10 }
1 n:扫描遍历次数 2 从2开始直到n我们进行倍数打标处理,每个循环到的数我们记为k 3 单次扫描的时间复杂度是O(n/k) 4 那么总的时间复杂度就是 5 T(n)=n/2+n/3+n/4+.....n/n(因为在算法的过程中我们是不断地筛掉的,所以说实际的时间复杂度是远远要比这个小的) 6 O(n)<T(n) 7 对于T(n)的求解,我们应用调和奇数的公式可以得到大致约为Ln(n) 8 所以说O(n)<O(n*logn)
先陈述我们的优化,在这里我们还是没有必要遍历整个范围,我们只需要遍历到sqrt(n)就可以了
证明,我先说明这个证明确实废了我一些功夫
首先回顾埃拉托色尼素数筛法,我们进行的操作是打标处理,如果我们在sqrt(n)停止了打标处理,会错误吗
反证法:
假设我们操作之后还是存在非素数d没有被打标,那么该素数的sqrt(d)<sqrt(n)显然,那么就说明d还存在一个因子k<sqrt(d)<sqrt(n),但是按照埃拉托色尼算法,这个k的所有的倍数我们全部都打标了,所以说矛盾
证明成功
对于优化1来说我们明显降低了遍历次数
1 for(int i=2;i<N;i++) 2 { 3 if(prime[i]) 4 { 5 long long int j; 6 save[++count]=i; 7 for(j=pow(i,2);j<N;j+=i) prime[j]=0; 8 } 9 }
从上面的埃拉托色尼算法的流程来看,我们对于某些数其实进行了重复筛选的结果
比如12,我们分别在2,3,的时候重复了筛选,为了优化重复筛选的弊端,我们引入快速线性筛法
1 memset(judge, 1, sizeof(judge)); 2 judge[1] = judge[0] = 0; 3 for (int i=2;i<N;i++) 4 { 5 if (judge[i]) prime[++countp] = i; //0 6 for (int j=1;j<=countp&&i*prime[j]<N;j++) //1 7 { 8 judge[i*prime[j]] = 0; 9 if (!(i%prime[j])) break; //2 10 } 11 }
1 d=d的最小素因子*w(该书可素可和,不考虑) 2 d的最小素因子必定小于等于w的最小素因子 3 (该结论应用反证法,如果d的最小素因子大于w最小素因子,那么对于d的最小素因子就不是一开始确定的值,所以说成立) 4 那么显然按照我们算法的流程来看的话在我们遍历到w的那个时候我们已经将d打标了,所以说和题设相矛盾 5 说明该算法对于筛素数是完全正确的,是不会漏筛的
1 #include"iostream" 2 #include"cstdio" 3 #include"cstdlib" 4 #include"time.h" 5 #define N 100000000 6 7 using namespace std; 8 9 bool judge[N]; 10 11 int main() 12 { 13 int count = 0; 14 double w = clock(); 15 memset(judge, 1, sizeof(judge)); 16 judge[1] = judge[0] = 0; 17 for (int i=2;i*i<N;i++) 18 { 19 if (judge[i]) 20 { 21 for (int j = 2;i*j < N;j++) judge[i*j] = 0; 22 } 23 } 24 for (int i = 2;i < N;i++) if (judge[i]) count++; 25 printf("%lf\n%d\n", clock() - w,count); 26 return 0; 27 }*/
2.Last question
转载于:https://www.cnblogs.com/mhpp/p/8182841.html
埃拉托色尼素数筛法(转)相关推荐
- P1865 A % B Problem (素数筛法,前缀和)
题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对于每次询问输出个数 t,如l或r∉[1,m]输出 Cros ...
- 斐波那契数列的3种求法及几种素数筛法
递推法 #include<stdio.h> long long sum[40];//也可以不用开数组 int main() {int n;scanf("%d",& ...
- P1217 [USACO1.5]回文质数 Prime Palindromes(素数筛法/打表)
P1217 [USACO1.5]回文质数 Prime Palindromes(素数筛法/打表) 一:埃氏筛(时间复杂度--nloglogn) 重点:一个数x是合数,则它的倍数也是合数 //用埃氏筛生成 ...
- 欧拉筛法原理C语言,素数筛法
素数筛 自古以来,素数就是一个有众多人研究的东西,而素数筛也是这些研究成果中的一个 素数筛是用来快速生成一个素数表的东西,比起生成素数的幼稚算法及其优化的方法,素数筛的速度更快,但是也常常会出现很多奇 ...
- C语言:素数筛法与分解素因数
一.素数筛法 素数筛法是关于求小于某个大数(正整数)的所有素数的算法,首先有理论:任何整数n≥2都可以分解成若干质数的乘积,即n=p1p2···pr. 用筛法求素数的基本思想是:把从1开始的.某一范围 ...
- 线性筛法求素数c语言,[算法]素数筛法(埃氏筛法线性筛法)
一.素数筛的定义 给定一个整数n,求出[1,n]之间的所有质数(素数),这样的问题为素数筛(素数的筛选问题). 二.埃氏筛法(Eratosthenes筛法) 埃氏筛法又叫做Eratosthenes筛法 ...
- 素数筛法(传统普通、朴素筛法、埃式筛法、欧拉筛法(线性筛))
素数筛法(普通.朴素筛法.埃式筛法.欧拉筛法) 1.题目 2.分析 3.代码 传统普通 朴素筛法 朴素筛法(6.14) 埃式筛法 埃式筛法(6.14) 欧拉筛法(线性筛) 欧拉筛法(线性筛 6.14) ...
- 素数判定(素数筛法)(欧拉)
这里主要说一下 素数筛法,该方法可以快速的选取出1~N数字中的所有素数.时间复杂度 远小于O(N*sqrt(N)) 方法为:从2开始,往后所有素数的倍数都不是素数.最后剩下的数都是素数. 再说说欧拉公 ...
- [原]素数筛法【Sieve Of Eratosthenes + Sieve Of Euler】
拖了有段时间,今天来总结下两个常用的素数筛法: 1.sieve of Eratosthenes[埃氏筛法] 这是最简单朴素的素数筛法了,根据wikipedia,时间复杂度为 ,空间复杂度为O(n). ...
最新文章
- openstack-mitaka之Telemetry服务(controller安装部署)
- sqlite3.OperationalError: database is locked
- ES6--基础语法(一)
- [ARM-assembly]-全局变量/静态全局变量/初始化/未初始化变量的存放位置分析
- SpringCloud微服务架构,Config 分布式配置中心,Bus 消息总线, Stream 消息驱动,Sleuth+Zipkin 链路追踪
- 中img拉伸_8个拉伸动作,帮你调动全身肌肉,提高柔韧性,缓解疲劳放松心情...
- Python 模块安装失败
- 组合数取模模板(2)
- 用CSS hack技术解决浏览器兼容性问题
- [Zer0pts2020]ROR1
- 使用Sbo用户自定义业务对象
- 计算机视觉 OpenCV【六:应用之颜色检测】
- Ural_1671. Anansi's Cobweb(并查集)
- android直接连接本地数据库文件,Android 直接连MySQL数据库
- https域名安全证书怎么配置
- KBEngine warring项目源码阅读(二) 登录和baseapp的负载均衡
- 【2022.1】触控板可以点击但无法滑动ThinkPad一个驱动问题
- 反爬虫原理与绕过实战
- 中学计算机课小课题,小学信息技术课堂有效教学的探索课题
- mysql set password_MySQL SET PASSWORD语法示例