C++埃氏筛

【C++】埃式筛法 【代码】【C++】埃式筛法。 阅读详情

引入

题目背景

给定正整数 n n n,请求出 1 , 2 , ⋯   , n 1,2,\cdots,n 1,2,⋯,n间所有质数

输入格式

一个正整数 n n n。

输出格式

一行多个正整数,表示 1 , 2 , ⋯   , n 1,2,\cdots,n 1,2,⋯,n中所有质数。

样例

样例 #1

样例输入 #1
3
样例输出 #1
2 3

数据范围

  • 对于 100 % 100 \% 100% 的数据, 1 ≤ n ≤ 1 0 6 1\leq n\leq10^6 1≤n≤106

暴力解决

遇事不决先暴力——洛谷大犇

最基础的思想就是枚举一遍 1 , 2 , ⋯   , n 1,2,\cdots,n 1,2,⋯,n,遇到质数就输出。
实现代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 1;
int n;
bool isprime(int x)
{
    if (x == 1) return 0;
    int i = 2;
    while (i < x) {
        if (x % i == 0) return 0;
        ++i;
    }
    return 1;
}
int main()
{
    scanf("%d", &n);
    for (int i = 2; i <= n; ++i)
        if (isprime(i)) printf("%d ", i);
       printf("\n");
    return 0;
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)

我们注意到,任何数 i ( x ≤ i < x ) i(\sqrt x\leq i<x) i(x ​≤i<x) 一定不整除 x x x。
所以枚举 i i i 时只需枚举 2 , ⋯   , x 2,\cdots,\sqrt x 2,⋯,x ​ 即可。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 1;
int n;
bool isprime(int x)
{
    if (x == 1) return 0;
    int i = 2;
    while (i * i <= x) { // any number that is bigger than sqrt(x) and smaller than x won't be a factor of x
        if (x % i == 0) return 0;
        ++i;
    }
    return 1;
}
int main()
{
    scanf("%d", &n);
    for (int i = 2; i <= n; ++i)
        if (isprime(i)) printf("%d ", i);
       printf("\n");
    return 0;
}

于是时间复杂度降到 O ( n n ) O(n\sqrt n) O(nn ​)。

埃氏筛基本思想

上面的代码中,每一个数都要判断是否被 2 2 2 整除。但是我们明显可以看到,只有 2 2 2是质数,其他偶数必定不是质数。所以这样实质上浪费了 O ( n ) O(n) O(n)的时间。
同理,对于一个质数 p p p, k p ( k ≥ 2 且 k ∈ Z + ) kp(k\geq2且k\in\Z^+) kp(k≥2且k∈Z+)1 必有 p p p 这个因数,所以 k p kp kp 一定不是质数。
那么,我们可以想到,不枚举 1 , ⋯   , n 1,\cdots,n 1,⋯,n,转而枚举 p 1 , p 2 , ⋯   , p m p_1,p_2,\cdots,p_m p1​,p2​,⋯,pm​,并将 { x ∣ x = k p i } ( k ≥ 2 ) \{x\mid x=kp_i\}(k\geq2) {x∣x=kpi​}(k≥2) 这个集合里所有数打上非质数标记(这里用布尔值最为方便,1表示不是质数)。

埃氏筛模版

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 1;
int n;
bool p[N] = {1, 1}; // p[i]: if i is not prime then p[i] = 1, otherwise it'll be 0
void fillp()
{
	for (int i = 2; i * i <= n; ++i)
		if (!p[i])
			for (int j = 2; i * j <= n; ++j) p[i * j] = 1;
}
int main()
{
    scanf("%d", &n);
    fillp();
    for (int i = 2; i <= n; ++i)
    	if (!p[i]) printf("%d ", i);
    return 0;
}

这样,我们省下很多重复的计算。
时间复杂度: O ( n log ⁡ log ⁡ n ) O(n\log\log n) O(nloglogn)2
这并不是没有代价的,空间复杂度从 O ( 1 ) O(1) O(1) 升到了 O ( n ) O(n) O(n),类似dp以空间换时间的做法。


  1. Z + \Z^+ Z+为正整数集,即 { 1 , 2 , ⋯   } \{1,2,\cdots\} {1,2,⋯} ↩︎

  2. 作者觉得还可以的证明:有点不严谨,但不繁琐 ↩︎

关于素数的埃氏筛法/区间筛法 C++(代码实现和详解) 前言 如果只对一个整数进行素性测试,通常O(n^1/2)的算法便足够了。而程序竞赛设计的主要是埃氏筛法等更高效的算法。如果要对许多整数进行素性测试,则需要利用更加高效的算法,此次以例题为媒介,介绍埃氏筛法和区间筛法。 一:埃氏筛法 eg:题目描述 给定整数n,请问n以内有多少个素数? n<=10^6 看到这,你可能会轻蔑的笑了,就这题,自己分分钟秒杀。但是请别急,下面介绍的埃氏算法,能让你更快解决。 埃氏算法氏和辗转相除法一样古老的算法,其大致思路如下: 首先,将2~n范围内的所有.. 阅读详情

相关推荐

埃氏筛算法解读(c++)

埃氏筛,全名为埃拉托斯特尼筛法(Sieve of Eratosthenes),是一种用于找出一定范围内所有质数的古老算法。它是由古希腊数学家埃拉托斯特尼在公元前3世纪发明的。

TWB1018的博客 2503

C++算法——埃氏筛

C++算法:埃氏筛

我发布的博客,快来抄答案吧 1944

C++实现埃氏筛法获取素数列表的算法及源代码

然后定义了一个primeList的vector数组,用来储存素数。从2开始遍历,如果是素数,把它添加进primeList中,并把它的倍数都标记成非素数。埃氏筛法的原理很简单,先从2开始,把所有的偶数排除,然后从3开始,把所有能被3整除的数排除,以此类推。每次找到一个素数,就把它的倍数都标记成非素数,这样,在不断筛选的过程中,剩下的数就都是素数了。埃氏筛法是一种常见的获取素数列表的算法,通过不断筛选出不是素数的数,最终得到所有的素数。本篇文章介绍了C++实现埃氏筛法获取素数列表的算法,并给出了完整的源代码。

PixelNovaO的博客 695

埃氏筛选素数(C++)

#include<bits/stdc++.h> using namespace std; int vis[10000]; int main(){ int n = 1000; int m = sqrt(n+0.5); for(int i=2;i<=m;i++) if(!vis[i]) //i从2开始,将2的倍数都筛掉,下一次i从3开始,把3的倍数全都筛掉 for(int j=i*i;j<=n;j+=i) vis[j] = 1;//赋值为1的都为非素数 f

weixin_46670664的博客 746

量化平台深度测评:聚宽 / 米筐 / 迅投 QMT 对比分析

本文对比测评国内主流量化交易平台聚宽、米筐和迅投QMT,从回测性能、实盘稳定性和高级功能三方面展开分析。测试显示:聚宽在低频策略回测中效率最高(128秒),米筐次之;迅投QMT凭借C++直连架构实现最低延迟(150ms)和最高订单撤销成功率(98.5%)。平台特色方面,QMT的智能拆单算法可减少25%滑点损失,聚宽的因子库支持版本控制和缓存复用。建议低频策略选聚宽,高频交易选QMT,团队协作优先考虑聚宽。测试数据均来自合规实盘环境,建议根据策略特性进行试用验证。

tianchi2009123的博客 7372

车载测试面试题总结

首先确认是什么问题,如果是测试软件的问题就先确定自己的测试方法有没有问题,如果没有问题,那就是测试软件的问题,这时候就需要提bug 进行跟踪,(比如BCM测试的时候,先明确测试的输入,对输入)进行需求分析,然后设计测试用例,进行用例评审,评审完执行测试用例形成最终的版本,台架分为:hil(黑尔)台架,单个控制器的台架、整车台架、车身台架、动力系统台架等,主要验证其功能,或者实车无法满足的测试环境。这个人不可能一直,点击几千次或者多少次几个小时连续点击,人不可能一直在点。因为要模拟一下这个稳定性,

woaxiaoqing的博客 7815

埃氏筛 C++

在 求指定范围内的质数个数 问题中,一般有试除法和筛法两大类。 试除法【时间复杂度为O(n^2)】容易超时。筛法中又有朴素筛、埃氏筛、欧拉筛。虽然欧拉筛【时间复杂度为O(n)】是线性的最优的,但是在理解和写比较复杂。一般用埃氏筛【时间复杂度为O(n loglogn)】就够了,埃氏筛代码简洁、更易理解。且本篇的埃氏筛还有一处细节优化。 埃氏筛原理 先假设每个数都是质数。 从 2 开始,2是质数,那么2的倍数:4、6、8、10、12、14、16... ...

m0_51336041的博客 3445

[A-21]ARMv8/v9-SMMU系统架构和功能概述

本文简述了SMMU的系统架构和核心功能

基层架构师的分享 1723

C++埃氏筛及应用

想要找出一个范围内的质数,用普通的枚举,并判断是否为质数的方法效率太低。我们可以用一个非常快速的方法:埃氏筛。埃氏筛法,全称为"埃拉托斯特尼筛法",是一种由埃及数学家埃拉托斯特尼提出的一种简单检定素数的方法。

Jiaochuancheng的博客 551

系统架构设计师重难点知识脑图

大家都知道现在的软考自从变成机考后,越来越难了,教程上的内容不仅全还细,几乎任何内容都有可能考,出题老师主打一个出其不意,比如2024年5月考试,连UML时序图的片段都考,这。软件工程、系统架构基础知识、系统质量属性与架构评估、软件架构的演化和维护、信息系统架构设计、层次式架构设计、云原生架构设计、面向服务架构设计、安全架构设计、大数据架构设计等。所以对于教程上的任何知识点,都需要去记忆。因此我在这里制作了一个脑图,将所有知识点集中在一个脑图中,通过首词组句法,记忆背诵,通过一个个的展开节点,加强记忆。

分享技术干货和灵感、推荐新书和好玩的项目、分享Java面试题 1103

SpringBoot + MyBatis-Plus 高效实现数据变更记录:从注解到通用审计方案(附源码)

*** 数据变更审计插件* 拦截增删改操作,自动记录变更日志*/@Component@Resource/*** 拦截SQL执行*/@Override/*** 数据变更审计插件* 拦截增删改操作,自动记录变更日志/*** 拦截SQL执行。

2601_94871597的博客 558

埃氏筛法 C++

主要我想讲讲 “ 碍事(埃氏) ” 筛法 (一)介绍 埃氏筛法 这是一个我感觉和辗转相除法一样NB的算法。原理也很简单。 首先将2到n范围内的整数写下来。其中2是最小的素数。将表中所有的2的倍数划去, 表中剩下的最小的数字就是3,他不能被更小的数整除,所以3是素数。 再将表中所有的3的倍数划去…… 以此类推,如果表中剩余的最小的数是m,那么m就是素数。 然后将表中所有m的倍数划去,像这样反复操作,就能依次枚举n以内...

TZchenym的博客 2994

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之OS模块配置详解(中)

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之OS模块配置详解(中)

weixin_42412049的博客 1513

埃氏筛/C++及python实现

埃氏筛即埃拉托斯特尼筛法,是由古希腊数学家埃拉托斯特尼提出的用于找出所有小于或等于给定自然数 N 的素数的算法。

2401_87089860的博客 369

【00】虹软2023届校招专场 ,计算机类笔试攻略(笔试考试时间、考察范围、笔试难度 等说明)

虹软科技2023校招笔试攻略:三大岗位类别(算法、算法优化、开发)分别于7月24日进行。题型包括选择题、编程题和问答题,其中算法类题目降低难度,编程题改为LeetCode模式。重点考察数学基础、机器学习、编程能力(C/C++/Python)、数据结构和算法优化等。建议根据投递岗位选择问答题,算法优化类注重系统知识和SIMD优化,开发类侧重多线程等实际应用能力。笔试结果将作为校招offer的重要参考。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 276

WPF实现棋盘式图片切换效果

实现效果如下: 思路:在自定义控件中放置两个Image控件,点击前后翻页按钮时对图片进行裁剪,随机打乱顺序后添加动作。 步骤: 1、MyImageControl控件 /// <summary> /// MyImageControl.xaml 的交互逻辑 /// </summary> public partial class MyImageControl : UserControl { public static r

dnazhd的博客 1125

C++数论————质数筛法(单独判断一个数,判断N个数) 埃氏筛法

质数想必大家都不陌生从小学到大质数的概念:一个数如果除了1和本身之外没有其他的因子,那么这个数被称为质数今天要讲两个知识点:在C++中如何判断一个数是否为质数在C++中如何判断1-N之间哪些数为整数这个知识点较为简单充分利用上面的概念我们用一个for循环来解决因为对于每个数来说,1和n都是他们的因子所以循环开始为2,终止为n-1。

lsy201009的博客 2444

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C++数学-数论筛质数-埃氏筛和线性筛流食般投喂

找到一个质数 x 的时候,我们可以从该数的 x 倍向后筛,因为小于 x 的倍数一定被之前的筛过了,例如:5 * 2,变个式,2 * 5,其实就是在找到质数 2 的时候已经筛过了。素数的判定那一块讲的是如何判断一个数是素数,如果此时想知道 [1,n] 中有多少个素数,或者是 [1,n] 中的素数里面,第 k 个素数是多少?任意大于 1 的质数,它的 k(k > 1) 倍就是合数。🤡从前往后遍历每个数 i,用 i 的质数倍去筛,同时,判断 i 是不是质数的倍数,是就停止,确保合数是被它的最小质因数筛掉的。

江屿风的博客 1305

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

GESP C++考试五级语法知识(二、埃氏筛和线性筛)

🌟《素数王国的两种超级筛子》

汉克老师的博客 1079

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

求[2,n]区间的所有质数 c++质数筛法(埃氏筛)

埃氏筛是一种快速求出2~n区间内的质数的算法。直接枚举判断100% TLE,必须用埃氏筛。它的基本思想是将合数筛掉,剩下的就是质数。求[2,n]区间的所有质数。

m0_73302074的博客 387

埃氏筛法C++

主要我想讲讲 “ 碍事(埃氏) ” 筛法 (一)介绍 埃氏筛法 这是一个我感觉和辗转相除法一样NB的算法。原理也很简单。 首先将2到n范围内的整数写下来。其中2是最小的素数。将表中所有的2的倍数划去, 表中剩下的最小的数字就是3,他不能被更小的数整除,所以3是素数。 再将表中所有的3的倍数划去…… 以此类推,如果表中剩余的最小的数是m,那么m就是素数。 然后将表中所有m的倍数划去,像这样反复操作,就能依次枚举n以内...

素有凌云志,我为代码狂 1875

c++ 埃氏筛法分解质因数

这是一种简单检定素数的算法。要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的倍数剔除,剩下的就是素数。(为了更直白,给大家放一张图像)输出有若干行,每行有两个数,分别代表这个数所包含的质因数和包含的个数(从小到大顺序输出)从图像中可以看到,该筛法先确定了质数,然后把它的所有倍数筛去,剩下的(1除外)就是质数。然后是这个题的要求(你可能觉得我油饼!但我们老师要求这样做!写到这里时我战战兢兢,因为我觉得没人会发这种无聊的文章了。废话不多说,首先来看看什么是埃氏筛法。

Liuyunrui110517的博客 515

Eratosthenes“埃氏筛法”求1000以内的素数C++

“埃氏筛法”是一种高效的求N以内素数的算法,时间复杂度为O(nloglogn),求100以内素数的“埃氏筛法”代码实现如下: #include #include int num[1001] = {0}; int primeCount = 0; int prime[1001]; void findPrime() { for (int i = 2; i <= 1000; ++i) {

DeciWine 3686

C/C++语言用埃氏筛选法快速筛选素数

思路 要枚举n以内的素数,可以用埃氏筛法。这是一个与辗转相除法一样古老的算法。 首先,将2到n范围内的所有整数写下来。其中最小的数字2是素数。将表中所有2的倍数都划去。表中剩余的最小数字是3,它不能被更小的数整除,所以是素数。再将表中所有3的倍数全都划去。依次类推,如果表中剩余的最小数字是m时,m就是素数。然后将表中所有m的倍数全部划去。像这样反复操作,就能依次枚举n以内的素数。 c++ 样例 当maxn=20时 首先 外面的循环 毋庸置疑 从2-20遍历需要20次(...

qq_52167324的博客 3346

埃氏筛 欧拉筛 c++

1.素数是仅能被它本身和1整除的任何整数。2.埃拉托斯特尼筛法,简称埃氏筛,是一种由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法。要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的倍数剔除,剩下的就是素数。3.判断一个数是不是素数,我们只用判[2,n]内有没有它的因子。在筛合数的时候也可以这样做,因为一个合数的最小质因子一定小于等于n。证明如下:设n为合数,那么n必有两个约数a,b 使得a*b=n。则a、b两个数中必有一个大于等于n,一个小于等于。

m0_73646108的博客 501

魔幻C++ 埃氏筛 质数

【代码】魔幻C++ 埃氏筛 质数。

qq_30121869的博客 25
上一篇: 排序算法之归并排序
下一篇: CF570D Tree Requests
peter_code
博客等级 码龄5年 41粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值