【模板】埃拉托色尼筛法(埃氏筛)

一、算法简介

在数论与编程竞赛中,求解 [ 1 , n ] [1,n] [1,n] 范围内的所有质数是常见的基础问题。埃拉托色尼筛法(Sieve of Eratosthenes) 是一种古老而高效的算法,可以在 O ( n log ⁡ log ⁡ n ) O(n \log \log n) O(nloglogn) 的时间复杂度内完成这一任务。


二、基本思想

埃氏筛的核心思想是:

对于每一个从小到大的质数 p p p,将其所有的倍数( 2 p , 3 p , 4 p , … 2p, 3p, 4p, \dots 2p,3p,4p,)标记为合数。
最终,所有未被标记的数就是质数。

举例说明:
n = 30 n = 30 n=30,初始认为 2 ∼ 30 2\sim 30 230 都是质数。
我们从 2 2 2 开始,依次把 4 , 6 , 8 , … 4,6,8,\dots 4,6,8, 标记为合数;
然后处理下一个未被标记的 3 3 3,再把 6 , 9 , 12 , … 6,9,12,\dots 6,9,12, 标记为合数;
如此反复,直到 n \sqrt{n} n


三、代码实现

以下是使用 C++ 编写的埃氏筛标准模板

#include<iostream>
#include<vector>
using namespace std;const int N = 1e5 + 10; // 设置一个足够大的常数N,表示数组大小vector<bool> ans(N, true); // 初始化素数表,默认所有数都是素数(true)
vector<int> nums;          // 用于存储最终得到的所有质数// 筛法主函数:获取1到n之间的所有素数
void get(int n)
{ans[0] = ans[1] = false; // 0 和 1 不是质数,直接标记为 false// 使用埃氏筛法,从 2 开始依次判断for (int i = 2; i <= n / i; i++)  // 等价于 i * i <= n{if (ans[i]) // 如果当前数 i 是质数(尚未被筛掉){// 从 i*i 开始,而不是 2*i:// 因为 i < j < i*i 范围内的 i 倍数,如 2*i, 3*i 等,已被更小的质数筛掉了for (int j = i * i; j <= n; j += i) // 枚举 i 的所有倍数{ans[j] = false; // 将 j 标记为合数}}}// 将所有的质数加入 nums 数组for (int k = 2; k <= n; k++){if (ans[k]){nums.push_back(k);}}
}

主函数调用如下:

int main()
{int n;cin >> n; // 输入要求筛到的最大范围get(n); // 执行筛法for (auto num : nums){cout << num << " "; // 输出所有质数}return 0;
}

四、关键优化说明

1. 为什么从 i * i 开始筛?

因为在遍历到质数 i i i 时,小于 i i i 的质数已经处理了 2 i , 3 i , . . . , ( i − 1 ) i 2i, 3i, ..., (i-1)i 2i,3i,...,(i1)i 的倍数。例如:

  • 6 = 2 × 3 6 = 2 \times 3 6=2×3 会在处理 2 2 2 时被筛掉;
  • 9 = 3 × 3 9 = 3 \times 3 9=3×3 会在处理 3 3 3 时被筛掉。

因此,从 i × i i \times i i×i 开始可以减少重复标记,提升效率。

2. 循环条件 i <= n / i

等价于 i * i <= n,这种写法可避免整数溢出,建议记住作为一种 防溢出技巧


五、时间与空间复杂度

  • 时间复杂度 O ( n log ⁡ log ⁡ n ) O(n \log \log n) O(nloglogn),非常高效
  • 空间复杂度 O ( n ) O(n) O(n),主要用于布尔数组 ans[]

六、样例输入输出

输入:

100

输出:

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

七、适用场景与拓展

  • 快速判断一个数是否为质数(配合布尔数组)
  • 枚举某范围内的所有质数(如用于欧拉函数、积性函数计算)
  • 可拓展为线性筛(Euler 筛)以避免重复标记(时间复杂度为 O ( n ) O(n) O(n)

八、结语

埃拉托色尼筛法是数论的入门利器,是多种算法的基础工具。建议熟练掌握并牢记模板结构。同时要理解从 i * i 开始标记的数学依据,避免盲记公式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/83738.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI Agent实战 - LangChain+Playwright构建火车票查询Agent

本篇文章将带你一步步构建一个智能火车票查询 Agent&#xff1a;你只需要输入自然语言指令&#xff0c;例如&#xff1a; “帮我查一下6月15号从上海到南京的火车票” Agent就能自动理解你的需求并使用 Playwright 打开 12306 官网查询前 10 条车次信息&#xff0c;然后汇总结果…

RabbitMQ的交换机和队列概念

&#x1f3ea; 场景&#xff1a;一个外卖平台的后台系统 假设你开了一家在线外卖平台&#xff1a; 饭店是消息的生产者&#xff08;Producer&#xff09;顾客是消息的消费者&#xff08;Consumer&#xff09;你开的外卖平台就是RabbitMQ消息系统 &#x1f501; 第一部分&…

德国马克斯·普朗克数学研究所:几何朗兰兹猜想

2025年科学突破奖 4月5日在美国洛杉矶揭晓&#xff1a;数学突破奖&#xff1a;德国马克斯普朗克数学研究所&#xff1a;几何朗兰兹猜想 德国马克斯普朗克数学研究所&#xff08;Max Planck Institute for Mathematics, MPIM&#xff09;在几何朗兰兹猜想的研究中扮演了核心角色…

TerraFE 脚手架开发实战系列(一):项目架构设计与技术选型

TerraFE 脚手架开发实战系列&#xff08;一&#xff09;&#xff1a;项目架构设计与技术选型 前言 在前端开发中&#xff0c;项目初始化往往是一个重复且繁琐的过程。每次新建项目都需要配置 webpack、安装依赖、设置目录结构等&#xff0c;这些重复性工作不仅浪费时间&#…

准确--CentOS 7.9在线安装docker

一、安装Docker前的准备工作 操作系统版本为CentOS 7.9&#xff0c;内核版本需要在3.10以上。确保能够连通互联网&#xff0c;为避免网络异常&#xff0c;建议关闭Linux的防火墙&#xff08;生产环境下请根据实际情况设置防火墙出入站规则&#xff09;。 # 查看内核版本 sudo…

中兴B860AV1.1强力降级固件包

中兴B860AV1.1强力降级固件包 关于中兴b860av1.1顽固盒子降级教程终极版 将附件解压好以后&#xff0c;准备一个8G以下的U盘重新格式化为FAT32格式后&#xff0c;并插入电脑 将以下文件及文件夹一同复制到优盘主目录下&#xff08;见下图&#xff09; 全选并复制到U盘主目录下&…

nacos-作为注册中心与springcloud整合(三)

前一篇文章nacos-简介和初体验&#xff08;一&#xff09;我们已经在服务器部署了nacos应用了。 在另外一篇文章中nacos-作为配置中心与springcloud整合&#xff08;二&#xff09;已经作为配置中心整合到springcloud 接下来让我们尝试把nacos作为注册中心和springcloud中整合&…

Seata的TC(事务协调器)高可用如何实现?

Seata的TC&#xff08;事务协调器&#xff09;确实运行在Seata服务进程中&#xff0c;其高可用实现和宕机恢复主要通过以下机制实现&#xff1a; 一、高可用架构 集群部署 多TC节点组成集群&#xff0c;通过注册中心&#xff08;如Nacos&#xff09;实现服务发现采用Raft协议实…

Mac安装docker desktop

一、背景 最近在学习Spring AI&#xff0c;于是在GitHub上找了个开源项目&#xff0c;个人觉得还是比较适合有Java基础和AI基础的同学学习的。GitHub地址如下&#xff1a; https://github.com/qifan777/dive-into-spring-ai 但是看了下运行环境需要 MySQL 8 Redis-Stack n…

【算法深练】二分答案:从「猜答案」到「精准求解」的解题思路

目录 前言 二分求最小值 1283. 使结果不超过阈值的最小除数 2187. 完成旅途的最少时间 1011. 在 D 天内送达包裹的能力 875. 爱吃香蕉的珂珂 3296. 移山所需的最少秒数 475. 供暖器 2594. 修车的最少时间 1482. 制作 m 束花所需的最少天数 3048. 标记所有下标的最早秒…

基于RK3588,飞凌教育品牌推出嵌入式人工智能实验箱EDU-AIoT ELF 2

在AIoT技术驱动产业变革的浪潮中&#xff0c;嵌入式人工智能已成为工业物联网、智慧交通、智慧医疗等领域创新突破的关键引擎。飞凌嵌入式教育品牌ElfBoard立足产业前沿&#xff0c;重磅推出嵌入式人工智能实验箱EDU-AIoT ELF 2&#xff0c;以“软硬协同、产教融合”为设计理念…

51单片机-IO扩展模块 pcf8575

PCF8575介绍 PCF8575 是 NXP&#xff08;原飞利浦半导体&#xff09;生产的一款通用 IC 总线 I/O 扩展器芯片&#xff0c;主要用于微控制器&#xff08;如 Arduino、STM32 等&#xff09;的 I/O 端口扩展。 主要特性 16位并行 I/O 端口&#xff1a;可以配置为输入或输出 IC 总…

Python3 学习(菜鸟)-02基本数据类型

1.多变量赋值 多变量被赋予相同的数值 多变量被赋予不同的数值 2.数值运算 除法 /&#xff1a;返回一个浮点数 除法 //&#xff1a;返回一个整数 3.列表 加号和星号 加号 是列表连接运算符 星号 * 是重复操作 list [ abcd, 786 , 2.23, runoob, 70.2 ] # 定义一个…

『uniapp』搜索功能+商品列表滚动效果(详细图文注释)

目录 预览效果准备工作代码分析与思路1. 页面结构主容器:`menber-container`搜索框:`u-search-inner`菜单:`u-menu-wrap`2. 数据模型`data()` 中的数据定义:3. 生命周期`onLoad(options)``onReady()``mounted()`4. 方法`search()``searchClear()``swichMenu(index)``getElRe…

微服务--消息队列mq

1. mq简介 消息队列是分布式系统中的异步通信中间件&#xff0c;采用"生产者-消费者"模型实现服务间解耦通信 核心作用 服务解耦异步处理流量削峰数据同步最终一致性 消息队列模式 发布/订阅模式&#xff1a;一对多广播工作队列模式&#xff1a;竞争消费死信队列…

第26节 Node.js 事件

Node里很多对象会分发事件&#xff1a; 每次有连接的时候net.Server会分发事件&#xff0c;当文件打开的时候fs.readStream会分发事件。所有能分发事件的对象都是 events.EventEmitter的实例。通过require("events");能访问这个模块。 一般来说&#xff0c;事件名都…

LangChain + MCP + vLLM + Qwen3-32B 构建本地私有化智能体应用

一、私有化智能体应用 在本专栏的前面文章基于Spring AI MCP实现了本地 ChatBI 问答应用&#xff0c;本文还是依据该场景&#xff0c;采用 LangChain vLLM Qwen3-32B MCP 技术栈构建该流程&#xff0c;整体过程如下图所示&#xff1a; 实现效果如下所示&#xff1a; 关于 M…

AKS升级路线最佳实践方案

前言 Kubernetes 社区大约每 4 个月发布次要版本&#xff0c;次要版本包括新增功能和改进。补丁发布更为频繁&#xff08;有时每周都会发布&#xff09;&#xff0c;适用于次要版本中的关键 Bug 修复。修补程序版本包括针对安全漏洞或主要 bug 的修复。对于受支持版本列表以…

树莓派智能小车基本移动实验指导书

1.安装LOBOROBOT库函数 LOBOROBOT.py代码如下&#xff1a; #!/usr/bin/python # -*- coding: utf-8 -*-import time import math import smbus import RPi.GPIO as GPIODir [forward,backward, ]class PCA9685:# Registers/etc.__SUBADR1 0x02__SUBADR2 …

如何对目标检测算法RT-DETR进行创新和改进:突破瓶颈,提升性能!

更多精彩&#xff0c;详见文末~~~ 在目标检测的高速发展中&#xff0c;RT-DETR作为DETR&#xff08;DEtection TRansformer&#xff09;的高效变体&#xff0c;凭借其优异的性能和较快的推理速度&#xff0c;已经成为许多实际应用中的首选算法。然而&#xff0c;尽管RT-DETR在…