线性筛素数
来源:互联网 发布:淘宝发货地址在哪里填 编辑:程序博客网 时间:2024/06/13 11:20
初始思想
思想是很简单的。假设要筛出1~n的素数,就先从最小的素数2开始,把2的j倍
void make_p(int n){ memset(vis,1,sizeof(vis)); vis[0]=vis[1]=0; for (int i=2;i<=n;i++) if (vis[i]) for (int j=2;j<=n/i;j++) vis[i*j]=false;}
实际上可以优化一下,只需要枚举到
void make_p(int n){ memset(vis,1,sizeof(vis)); vis[0]=vis[1]=0; for (int i=2;i<=sqrt(n);i++) if (vis[i]) for (int j=i;j<=n/i;j++) vis[i*j]=false;}
优化过后的初始思想其实很不错了,但是还可以做到更好。
优化思想
我们会发现初始思想有些数筛了多次,比如30,在2*15、3*10以及5*6都筛过了。这样就会导致效率不高(但是实际上好像初始思想并不是特别糟糕,刘汝佳说是O
优化思想可以保证1~n的任何数都不会筛过重,我们先看代码,再来讨论效率的问题:
int make_p(int n){ memset(vis,1,sizeof(vis));vis[0]=vis[1]=false; for (int i=2;i<=n;i++) { if (vis[i]) p[++p[0]]=i; for (int j=1;j<=p[0]&&p[j]*i<=n;j++) { vis[p[j]*i]=false; if (i%p[j]==0) break; //判断语句 } }}
看起来好像并不是线性的,但是实际上我们可以证明没有任何数筛了两次(即效率是线性的)。
①当i是素数的时候,由于目前i是最大的素数,所以任何一个已知素数*i之前都不会出现过。
②当i不是素数的时候,枚举j时的那个判断语句就起到作用了。设i唯一分解之后最小的素数是
阅读全文
5 1
- 线性筛素数
- 线性时间筛素数
- 线性素数筛
- 线性时间素数筛
- 线性筛素数模板
- 线性素数筛法
- [线性筛]素数个数
- 线性筛求素数
- 线性筛素数
- 线性筛素数法
- 线性筛素数
- 线性筛素数
- 素数线性筛
- 线性筛素数
- 线性筛素数
- 线性素数筛模板
- 线性筛素数
- 线性筛素数
- Node.js学习笔记
- Android 解析RecyclerView(2)——带顶部View和底部View的RecyclerView
- 音质检测的算法创新与实现
- Java 多模块项目创建
- iptables详解
- 线性筛素数
- python模块之搜索路径和路径搜索
- JavaScript的部分基本循环
- 找工作笔试面试那些事儿(4)---C++函数高级特征
- SpringMVC入门项目 注解版
- UIKit之UIImageView
- java-SE-1
- Codevs 1036:商务旅行——题解
- 树的孩子表示法,树的兄弟表示法,树的存储结构详解,数据结构-树的学习(2)