[算法]素数筛法(埃氏筛法&线性筛法)
一、素数筛的定义
给定一个整数n,求出[1,n]之间的所有质数(素数),这样的问题为素数筛(素数的筛选问题)。
二、埃氏筛法(Eratosthenes筛法)
埃氏筛法又叫做Eratosthenes筛法,一般叫做埃氏筛。埃氏筛的思想是:
\(\forall x\in Z\)的倍数\(2x,3x,...\)都不是质数。
因此我们可以从2开始有小到大扫描每个数\(x\),并把\(x\)的倍数\(2x,3x,4x,...\)标记为合数。当这个某个数\(y\)被扫描到的时候,如果\(y\)没有被标记为合数,那么\(y\)就属于质数。
Eratosthenes筛法的复杂度为\(O(NloglogN)\)。效率非常接近线性。
以下为Eratosthenes筛法模板:
inline int Eratosthenes(int n){
for(int i=1;i<=n;i++) is_p[i]=1;
memset(prime,0,sizeof(prime));
is_p[1]=is_p[0]=0;
for(int i=1;i<=n;i++){
if(!is_p[i]) continue;
prime[++tot]=i;//prime[]存储了[1,n]的所有质数
for(int j=i*2;j<=n;j+=i) is_p[j]=0;//j为合数
}
return tot;
}
三、线性筛法
我们知道,一个算法的复杂度组成有一类是因为重复的计算。这就是埃氏筛的问题所在,埃氏筛会重复标记已标记的合数。例如12会被质数2重复标记,同时也会被3标记。如果我们仅能标记一次合数就好了。
线性筛法通过从大到小不断累乘质因子的方法标记合数,即12的标记方式为:\(12=6\times 2=(3\times2)\times2\)。
实现方式为:
1.依次扫描[2,n]的每一个数a
2.若没有被标记为合数,说明a是质数,此时保存起来
3.依次扫描\(a\times prime[x]\leqslant n\)的每一个质数,标记\(a\times prime[x]\)为合数,且保证prime[x]为\(a\times prime[x]\)的最小质因子。
因为每个合数只会被它的最小质因子筛一次,所以线性筛的复杂度为\(O(N)\)。
以下为线性筛法的模板:
int notp[N],prime[N];
inline int get_primes(int n){
int tot=0;
for(int i=2;i<=n;i++){
if(!notp[i]) prime[++tot]=i;
for(int j=1;j<=tot,i*prime[j]<=n;j++){
notp[i*prime[j]]=1;//标记合数,此时prime[j]是合数i*prime[j]的最小素因子
if(i%prime[j]==0) break;
//一个小合数与大质数 可以被 一个大合数与小质数 替代
//3*6=18,同样的,2*9=18。此时我们不如让2*9标记18
}
}
return tot;
}
四、一个性质
- 任何一个合数n必定包含一个不超过\(\sqrt n\)的质因子。

[算法]素数筛法(埃氏筛法&线性筛法)的更多相关文章
- 素数判断-----埃氏筛法&欧拉筛法
埃氏筛法 /* |埃式筛法| |快速筛选素数| |15-7-26| */ #include <iostream> #include <cstdio> using namespa ...
- poj 2689Prime Distance(区间素数)埃氏筛法
这道题的L和R都很大,所以如果直接开一个1~R的数组明显会超时.但是R-L并不大,所以我们考虑把这个区间(L--R)移动到(1--(R-L+1))这个区间再开数组(就是把每个数减L再加1).接下来先用 ...
- GDUFE-OJ 1359校庆素数 埃氏筛法
Problem Description: 包含33的素数称为校庆素数. 她想知道在L和R之间(包含L和R)有多少个校庆素数. 比如 2333 就是一个校庆素数. Input: 输入的第一行包括一个T( ...
- 洛谷P3383 【模板】线性筛素数 (埃拉托斯特尼筛法)
题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范围和查询的个数. 接下来M行每行 ...
- 埃氏筛法求素数&构造素数表求素数
埃氏筛法求素数和构造素数表求素数是一个道理. 首先,列出从2开始的所有自然数,构造一个序列: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1 ...
- 埃氏素数筛法(Eratosthenes)
埃氏筛法: 对于每一个小于n的非负整数p,删去2p,3p,4p......,当处理完所有数后,还没有删除的就是素数. 想法:用a记录素数表,a[i]=1表示不是素数,a[i]=0表示是素数. #inc ...
- (第三场) H Diff-prime Pairs 【数论-素数线性筛法+YY】
题目链接 题目描述 Eddy has solved lots of problem involving calculating the number of coprime pairs within s ...
- Codeforces Round #270 A. Design Tutorial: Learn from Math【数论/埃氏筛法】
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...
- <转载>一般筛法和快速线性筛法求素数
素数总是一个比较常涉及到的内容,掌握求素数的方法是一项基本功. 基本原则就是题目如果只需要判断少量数字是否为素数,直接枚举因子2 ..N^(0.5) ,看看能否整除N. 如果需要判断的次数较多,则先用 ...
随机推荐
- Java容器的常见问题
记录Java容器中的常见概念和原理 参考: https://github.com/wangzhiwubigdata/God-Of-BigData#三Java并发容器 https://blog.csdn ...
- 新手版超详细LoadRunner12完整安装+汉化过程
01下载 首先从百度网盘获取到这几个文件(网盘地址会附在文末,过期请联系): 我安装的是社区版+中文汉化过的,使用我只下载了第一个和第三个文件,下面我将讲一下如何安装. 02安装社区版 1.选择“ ...
- Mysql常用sql语句(一)- 操作数据库
21篇测试必备的Mysql常用sql语句,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1683347.html ...
- git push错误,如何回滚
--> git push Counting objects: 81, done.Delta compression using up to 4 threads.Compressing objec ...
- Android通知栏前台服务
一.前台服务的简单介绍 前台服务是那些被认为用户知道且在系统内存不足的时候不允许系统杀死的服务.前台服务必须给状态栏提供一个通知,它被放到正在运行(Ongoing)标题之下--这就意味着通知只有在这个 ...
- Hive常用的10个系统函数及作用
聚合函数 函数处理的数据粒度为多条记录. sum()—求和 count()—求数据量 avg()—求平均直 distinct—求不同值数 min—求最小值 max—求最人值 分析函数 Analytic ...
- vue基础指令学习
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- coding++:拦截器拦截requestbody数据如何防止流被读取后数据丢失
1):现在开发的项目是基于SpringBoot的maven项目,拦截器的使用很多时候是必不可少的,当有需要需要你对body中的值进行校验,例如加密验签.防重复提交.内容校验等等. 2):当你开开心心的 ...
- Java 垃圾回收机制方法,判断对象存活算法
垃圾回收机制: 不定时去堆内存中清理不可达对象.不可达的对象并不会马上就会直接回收, 垃圾收集器在一个Java程序中的执行是自动的,不能强制执行,即使程序员能明确地判断出有一块内存已经无用了,是应该回 ...
- 请问一下大佬们,我的项目compile编译的时候总是编译报错
这是执行compile编译的结果 这是加上参数-X之后的结果