素数线性筛(O(N)!!!)
来源:互联网 发布:宝贝关键词怎么优化 编辑:程序博客网 时间:2024/06/13 11:39
我们先来看一下最经典的埃拉特斯特尼筛法。时间复杂度为O(n loglog n)
int ans[MAXN]; void Prime(int n) { int cnt=0; memset(prime,1,sizeof(prime)); prime[0]=prime[1]=0; for(int i=2;i<n;i++) { if(vis[i]) { ans[++cnt]=i;//保存素数 for(int j=i*i;j<n;j+=i)//i*i开始进行了稍微的优化 prime[j]=0;//不是素数 } } return; }
通过观察我们可以发现一个问题,这种方法会重复筛除合数,影响了效率。
比如,当30,在2*15筛了一次,在5*6又筛了一次。
所以我们有了一个快速线性筛法,不会重复筛选同一个数,所以几乎是线性的。
首先我们要知道一个条件
任何一个合数都可以表示成一连串质数的乘积
每个合数有一个最小的质因子,用这个质因子筛去这个合数,这样时间就是线性的了。
至于实现,先来看下代码
#include <cstdio>#include <iostream>using namespace std;int prime[20000];//记录质数int vis[20000];//标记是否是质数int cnt;void Prime(int n){ vis[1]=1; for(int i=2;i<=n;i++) { if(!vis[i]) prime[++cnt]=i; for(int j=1;j<=cnt&&i*prime[j]<=n;j++) { vis[i*prime[j]]=1; if(!(i%prime[j])) break; } }}int main(){ int n; scanf("%d",&n); Prime(n); for(int i=1;i<=n;i++) if(!vis[i]) printf("%d ",i); return 0;}
刚刚说的让合数被它最小的质因数筛去在代码中的体现就是这句:
if(!(i%prime[j]))
break;
由于枚举是从小到大的,所以prime数组中的质数是递增的
如果i%prime[j]为零(即i为prime[j]的倍数)
那么i*prime[j+1]这个合数一定已经被prime[j] 乘以某个数筛掉了
因为i中含有prime[j], prime[j] 比 prime[j+1] 小
在满足i%prme[j]==0这个条件之前以及第一次满足改条件时,prime[j]必定是prime[j]*i的最小因子。
这样我们便实现的线性筛
阅读全文
1 0
- 素数线性筛(O(N)!!!)
- 线性筛选素数法(O(n)复杂度)
- ACM 求素数 线性筛法 o[n]
- 线性筛 o(n)复杂度打素数表
- (模板)线性筛素数
- O(n)欧拉函数+素数筛选
- 素数打表,复杂度(Onlogn)和O(n)(对与10^7来说线性快两倍) + 分解质因数
- Codeforces Round #142 (Div. 2) B. T-primes (数学、O(n)筛素数)
- 筛素数 时间复杂度:O(N)
- 【筛素数表证明】【O[n]】
- 洛谷P3383 线性筛素数(线性筛)
- POJ 3006(线性筛素数)
- 线性筛法(欧拉筛法)求素数
- 【模板】线性筛素数(埃筛+欧筛)
- 素数筛法求素数(线性时间)
- 求n很大时求,<= n的素数的个数(时间复杂度o(n ^ 2 / 3)模板
- 素数筛选 O(n)算法
- O(NloglogN)素数筛法与O(N)素数筛法的对比测试
- 自定义圆形Drawable
- 动态链接库(二)-访问MFC动态链接库c++类和资源
- 在React-Native中使用redux
- 51-汇编学习笔记(一)
- 离散题目5
- 素数线性筛(O(N)!!!)
- LeetCode-582. Kill Process (JAVA)杀死进程
- Android EditText 去除编辑功能,保留点击移到光标效果。去除 屏蔽 双击全选
- 用swoole framework 实现远程接口调用RPC
- c++导出全局变量给lua使用
- 读取指定字符串后面的数值
- POJ
- 模仿探探的左右滑动切换卡片功能
- kipmi0进程导致CPU使用率过高