博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线性素数筛模板+理解
阅读量:4314 次
发布时间:2019-06-06

本文共 1013 字,大约阅读时间需要 3 分钟。

线性筛其实NOIp2017之前打过线性筛板子,不过那时候就没理解,临阵磨枪顾不了那么多。

学习数论的时候用到了,又看了一遍。作为一个性子比较急的人找了好几个博客都看不下去,因此花了很长时间才搞懂。

O(sqrt(n))判断n是不是质数就不多赘述了。素数筛之所以叫“筛”是因为它的基本思想是对于1-n批量判素数,由当前已知素数筛去后面的是该素数倍数的合数,以此剩下质数。因此,根据这一基本思想,我们可以初步写出一种粗劣的素数筛算法:

int n;const int sz=1e6+5;bool h[sz]={
0};//h[i]=0表示i是质数,反之不是int z[sz],len;//z用于储存已知素数,len表示已知素数的个数h[1]=1;for(int i=2;i<=n;i++){ if(h[i]==0)z[++len]=i; for(int j=1;j<=len&&z[j]*i<=n;j++)h[z[j]*i]=1;}

然后大家会发现,n一大这个算法的效率就非常呵呵了……

尝试优化这个算法。

分析可以发现,这个算法的效率之所以会低,是因为同一个数有很多质因子,因此会被筛很多遍。如果我们可以让一个数只被筛一次,就可以保证效率优化到O(n)。(这不是废话吗摔)

那么,如何让一个数只被筛一次呢?可以考虑只用这个数最小的质数或者最大的质数去筛这个数。我们的原算法是,对于素数p,晒去p*x(x是大于1的正整数),若p是(p*x)的最小质因数,只要使得p不大于x中的所有质因数即可。原算法可以看作是枚举x,对于每个x从小到大枚举p,我们只要在p增大到恰为x的最小质因数时去枚举下一个x即可。

代码如下:

int n;const int sz=1e6+5;bool h[sz]={
0};//h[i]=0表示i是质数,反之不是int z[sz],len;//z用于储存已知素数,len表示已知素数的个数h[1]=1;for(int i=2;i<=n;i++){ if(h[i]==0)z[++len]=i; for(int j=1;j<=len&&z[j]*i<=n;j++){ h[z[j]*i]=1; if(i%z[j]==0)break; }}

转载于:https://www.cnblogs.com/BLeaves/p/8641120.html

你可能感兴趣的文章
Mysql支持的数据类型(总结)
查看>>
对测试转开发的一些想法
查看>>
MVC文件上传08-使用客户端jQuery-File-Upload插件和服务端Backload组件让每个用户有专属文件夹...
查看>>
html模板中调用变量
查看>>
pacs dicom3.0 DCMTK EFilm
查看>>
大气登录页面
查看>>
应用程序缓存的应用(摘抄)
查看>>
C#析构函数,类运行结束后运行
查看>>
在LAMP的生产环境内添加PHP的cURL扩展模块
查看>>
AMH 软件目录介绍
查看>>
你可能使用了Spring最不推荐的注解方式
查看>>
java常见3种文件上传速度对比和文件上传方法详细代码
查看>>
SVD总结
查看>>
python基础教程(三)
查看>>
PL SQL Developer中文乱码
查看>>
字符串知识大全
查看>>
软件目录结构规范及堂兄弟文件引用
查看>>
H5 WebSocket通信和WCF支持WebSocket通信
查看>>
文件上传
查看>>
不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况...
查看>>