线性筛法求素数
2016-04-15 23:13
274 查看
为什么称为线性,因为普通的筛法重复了好多次,冗余,而线性筛法避免了冗余。
①如果 i 都是是素数的话,那简单,一个大的素数 i 乘以不大于 i 的素数,这样筛除的数跟之前的是不会重复的。筛出的数都是 N=p1*p2的形式, p1,p2之间不相等
②如果 i 是合数,此时 i 可以表示成递增素数相乘 i=p1*p2*...*pn, pi都是素数(2<=i<=n), pi<=pj ( i<=j )p1是最小的系数。
根据“关键处2”的定义,当p1==prime[j] 的时候,筛除就终止了,也就是说,只能筛出不大于p1的质数*i。
重要的就是if(!(i % prime[j]))break;
为什么要这样呢,因为对于当前的合数,这个合数每次相乘一个小的素因子就会得到一个新的合数,此时不能继续。对于后面的合数,他能够被比他小的某一个数乘以一个最小素因子后得到,所以不需要再遍历每一个数。
模板:
①如果 i 都是是素数的话,那简单,一个大的素数 i 乘以不大于 i 的素数,这样筛除的数跟之前的是不会重复的。筛出的数都是 N=p1*p2的形式, p1,p2之间不相等
②如果 i 是合数,此时 i 可以表示成递增素数相乘 i=p1*p2*...*pn, pi都是素数(2<=i<=n), pi<=pj ( i<=j )p1是最小的系数。
根据“关键处2”的定义,当p1==prime[j] 的时候,筛除就终止了,也就是说,只能筛出不大于p1的质数*i。
重要的就是if(!(i % prime[j]))break;
为什么要这样呢,因为对于当前的合数,这个合数每次相乘一个小的素因子就会得到一个新的合数,此时不能继续。对于后面的合数,他能够被比他小的某一个数乘以一个最小素因子后得到,所以不需要再遍历每一个数。
模板:
void eular() { cnt = 0; int m = MAXN; memset(isnotprime,0,sizeof(isnotprime)); for(int i = 2; i <= m; i ++){ if(!isnotprime[i]){ prime[cnt++] = i; } for(int j = 0; j < cnt && 1LL * i * prime[j] < m; j++){ isnotprime[prime[j]*i] = 1; if(i % prime[j] == 0) break; } } }
相关文章推荐
- java中的换行符
- sicily1142(深搜加剪枝)
- C基础学习的简单记录——基础练习(3)
- C++第二次作业补充
- Linux后门入侵检测工具,附bash漏洞解决方法[转载]
- android ndk开发(二)实现一个官方demo
- 深拷贝(mutableCopy)与浅拷贝(Copy)详解
- S5PV210的中断处理机制(多数CPU通用)
- 数据缓存——CoreData的使用
- 网络编程--WebView
- 隐藏或者显示APP状态栏
- redis安装以及问题解决
- 细说gulp
- 丑的一笔的普通平衡树ver的splay
- HDU1828 Picture(线段树+扫描线求周长并)
- HTTP 错误 404.2 - Not Found 由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面。
- 利用beautifulsoup 取图片
- 递归查询,查询文件夹中是否有MP4格式的文件
- 视频合并问题
- hihoCoder 1014 Trie树(字典树)