线性欧拉筛
线性筛:高效求解素数
在数论中,素数的筛选是一个经典的问题。最常见的素数筛选方法是埃拉托斯特尼筛法,其时间复杂度为 O ( n log log n ) O(n\log \log n) O(nloglogn),非常适合求解小范围内的素数。随着问题规模的增大,传统的埃拉托斯特尼筛法可能会遇到效率瓶颈,因此线性筛(Linear Sieve)作为一种优化算法应运而生,它通过减少不必要的计算,优化了素数筛选的过程,具有 O ( n ) O(n) O(n) 的时间复杂度。
本文将详细介绍线性筛法,并通过代码实现和分析,帮助你更好地理解其原理和应用。
1. 线性筛法的原理
线性筛法的核心思想是:通过直接利用已筛选出的素数来筛去合数,而避免像埃拉托斯特尼筛法中那样重复筛选已经合数的数。具体来说,我们通过对每个数 i i i 判断它是否为素数,若是素数,则标记它的倍数为合数。关键的优化点在于:每个素数 p p p 只会在第一次筛选其倍数时参与筛选。
1.1 线性筛法的步骤
- 初始化:准备一个布尔数组
is_prime[]来标记每个数是否为素数,初始时所有数都标记为素数。 - 筛选过程:
- 从小到大遍历每个数 i i i。
- 如果 i i i 是素数,则标记它的倍数为合数。
- 在标记倍数时,确保每个素数 p p p 只参与标记一次 p × p , p × ( p + 1 ) , … p \times p, p \times (p+1), \dots p×p,p×(p+1),…,而不会重复标记。
1.2 线性筛的特点
- 时间复杂度: O ( n ) O(n) O(n),因为每个素数只参与一次倍数的筛选。
- 空间复杂度: O ( n ) O(n) O(n),需要一个大小为 n n n 的布尔数组来记录素数信息。
- 效率:相对于传统的埃拉托斯特尼筛法,线性筛在处理大量数据时更为高效,避免了不必要的重复操作。
2.示例图解(n=20为例)
| 当前数 (i) | 是否质数? | 筛除的数 (i×primes[j]) | 质数列表 (primes) | 说明 |
|---|---|---|---|---|
| 1 | ❌ 否 | — | [] | 1 不是质数,跳过。 |
| 2 | ✅ 是 | 2×2=4 | [2] | 首次遇到 2,加入质数列表,并筛除 2×2=4。 |
| 3 | ✅ 是 | 3×2=6, 3×3=9 | [2, 3] | 首次遇到 3,加入质数列表,依次筛除 3×2=6 和 3×3=9。 |
| 4 | ❌ 否 | 4×2=8 | [2, 3] | 4 被 2 整除,仅筛除 4×2=8,之后停止(因为 4%2==0)。 |
| 5 | ✅ 是 | 5×2=10, 5×3=15, 5×5=25 | [2, 3, 5] | 首次遇到 5,加入质数列表,筛除 10,15,25>20 停止。 |
| 6 | ❌ 否 | 6×2=12 | [2, 3, 5] | 6 被 2 整除,仅筛除 6×2=12,之后停止。 |
| 7 | ✅ 是 | 7×2=14, 7×3=21, 7×5=35 | [2, 3, 5, 7] | 首次遇到 7,加入质数列表,筛除 14,21>20 停止。 |
| 8 | ❌ 否 | 8×2=16 | [2, 3, 5, 7] | 8 被 2 整除,仅筛除 8×2=16,之后停止。 |
| 9 | ❌ 否 | 9×2=18, 9×3=27 | [2, 3, 5, 7] | 9 被 3 整除,筛除 18,27>20 停止。 |
| 10 | ❌ 否 | 10×2=20 | [2, 3, 5, 7] | 10 被 2 整除,仅筛除 10×2=20,之后停止。 |
| 11 | ✅ 是 | 11×2=22, 11×3=33, 11×5=55 | [2, 3, 5, 7, 11] | 首次遇到 11,加入质数列表,但所有乘积 >20,直接跳过筛除。 |
| 12 | ❌ 否 | 12×2=24 | [2, 3, 5, 7, 11] | 12 被 2 整除,仅筛除 12×2=24(24>20 实际不操作),之后停止。 |
| 13 | ✅ 是 | 13×2=26, 13×3=39 | [2, 3, 5, 7, 11, 13] | 首次遇到 13,加入质数列表,所有乘积 >20,跳过筛除。 |
| 14 | ❌ 否 | 14×2=28 | [2, 3, 5, 7, 11, 13] | 14 被 2 整除,28>20 不操作,直接停止。 |
| 15 | ❌ 否 | 15×2=30, 15×3=45 | [2, 3, 5, 7, 11, 13] | 15 被 3 整除,所有乘积 >20,跳过筛除。 |
| 16 | ❌ 否 | 16×2=32 | [2, 3, 5, 7, 11, 13] | 16 被 2 整除,32>20 不操作,直接停止。 |
| 17 | ✅ 是 | 17×2=34, 17×3=51 | [2, 3, 5, 7, 11, 13, 17] | 首次遇到 17,加入质数列表,所有乘积 >20,跳过筛除。 |
| 18 | ❌ 否 | 18×2=36, 18×3=54 | [2, 3, 5, 7, 11, 13, 17] | 18 被 2 整除,所有乘积 >20,跳过筛除。 |
| 19 | ✅ 是 | 19×2=38, 19×3=57 | [2, 3, 5, 7, 11, 13, 17, 19] | 首次遇到 19,加入质数列表,所有乘积 >20,跳过筛除。 |
| 20 | ❌ 否 | 20×2=40 | [2, 3, 5, 7, 11, 13, 17, 19] | 20 被 2 整除,40>20 不操作,直接停止。 |
最终结果
• 质数列表:[2, 3, 5, 7, 11, 13, 17, 19]
• 关键规则:
- 每个合数仅被最小质因数筛除一次(如
12只会被2×6筛除,不会被3×4重复筛)。- 终止条件:当
i×primes[j] > n时停止筛除(如5×5=25>20直接跳过)。
3. 线性筛法的代码实现
推荐题目: 洛谷3383 线性筛
以下是使用 Python 实现的线性筛法代码:
def linear_sieve(n):# 创建一个布尔数组,用来标记每个数是否是素数is_prime = [True] * (n + 1)# 记录所有的素数primes = []# 从2开始筛选for i in range(2, n + 1):if is_prime[i]:primes.append(i)# 遍历所有素数的倍数for p in primes:if i * p > n: # 超过范围,停止breakis_prime[i * p] = Falseif i % p == 0: # 保证每个素数只参与标记一次breakreturn primes# 测试
n = 30
primes = linear_sieve(n)
print(f"小于等于 {n} 的所有素数是:", primes)
2.1 代码解析
is_prime[]:布尔数组,用来记录从 2 2 2 到 n n n 的每个数是否为素数。初始化时设为True,表示所有数默认是素数。primes[]:用于存储所有的素数。- 主循环:从 2 2 2 开始,逐个判断每个数是否为素数。如果是素数,就将它的所有倍数标记为合数。
- 内循环:遍历已经找到的素数列表,筛去它们的倍数。由于线性筛法中每个素数只参与标记一次倍数,因此避免了重复计算。
2.2 示例输出
输入:
n = 30
输出:
小于等于 30 的所有素数是: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
3. 线性筛法的优势与应用
3.1 优势
- 时间复杂度优化:传统的埃拉托斯特尼筛法在筛选过程中会重复筛除一些合数,而线性筛法保证每个素数只参与标记一次,从而避免了重复计算。
- 空间复杂度低:与其他优化算法(如线性筛的空间复杂度为 O ( n ) O(n) O(n))相比,线性筛方法的空间利用相对较高,能够在更大的范围内处理素数问题。
3.2 应用场景
- 素数生成:当需要生成一个区间内的所有素数时,线性筛法提供了高效的算法。
- 区间素数筛选:在一些区间范围内筛选素数时,可以利用线性筛法进行优化。
- 数学问题:在数论、密码学等领域中,素数的筛选是常见的操作,而线性筛法能够提供高效的解法。
4. 线性筛法的优化
线性筛法的核心思想就是减少不必要的筛选,并利用已经筛选出的素数来避免重复工作。虽然它已经比传统的埃拉托斯特尼筛法更高效,但在一些实际场景下,仍然可以通过以下方式进行进一步优化:
- 优化内循环:内循环只需要检查当前素数 p p p 是否小于等于当前数的平方根,避免多余的循环。
- 使用更紧凑的数据结构:通过位运算等方式优化布尔数组的存储,进一步节省空间。
5. 总结
线性筛法是一种高效的素数筛选算法,具有 O ( n ) O(n) O(n) 的时间复杂度,相较于传统的埃拉托斯特尼筛法,避免了重复计算,能够更快速地生成素数。其在大规模素数筛选和数论问题中具有广泛应用,尤其在需要处理大范围素数时,线性筛法无疑是一种非常有效的工具。
通过对线性筛法的深入理解与实现,我们能够更好地应对需要高效素数筛选的各种问题,并在实践中提供优异的性能表现。
相关文章:
线性欧拉筛
线性筛:高效求解素数 在数论中,素数的筛选是一个经典的问题。最常见的素数筛选方法是埃拉托斯特尼筛法,其时间复杂度为 O ( n log log n ) O(n\log \log n) O(nloglogn),非常适合求解小范围内的素数。随着问题规模的增大&…...
Flutter vs React Native:跨平台移动开发框架对比
文章目录 前言1. 框架概述什么是 Flutter?什么是 React Native? 2. 性能对比Flutter 的性能表现React Native 的性能表现总结: 3. 开发体验对比3.1 开发效率3.2 UI 组件库 4. 生态系统对比5. 适用场景分析6. 结论:如何选择&#x…...
用matlab搭建一个简单的图像分类网络
文章目录 1、数据集准备2、网络搭建3、训练网络4、测试神经网络5、进行预测6、完整代码 1、数据集准备 首先准备一个包含十个数字文件夹的DigitsData,每个数字文件夹里包含1000张对应这个数字的图片,图片的尺寸都是 28281 像素的,如下图所示…...
AI辅助开发插件
适合Java程序员的AI辅助开发插件,按功能和适用场景分类: 1. 飞算JavaAI • 特点:从需求分析到代码生成的全流程智能引导,支持Maven、Gradle等主流工具,一键生成完整工程代码,包括配置文件、源代码和测试资…...
【AI4CODE】5 Trae 锤一个基于百度Amis的Crud应用
【AI4CODE】目录 【AI4CODE】1 Trae CN 锥安装配置与迁移 【AI4CODE】2 Trae 锤一个 To-Do-List 【AI4CODE】3 Trae 锤一个贪吃蛇的小游戏 【AI4CODE】4 Trae 锤一个数据搬运工的小应用 1 百度 Amis 简介 百度 Amis 是一个低代码前端框架,由百度开源。它通过 J…...
npm webpack打包缓存 导致css引用地址未更新
问题如下: 测试环境配置: publicPath: /chat/,生产环境配置: publicPath: /,css中引用背景图片 background-image: url(/assets/images/calendar/arrow-left.png);先打包测试环境,观察打包后的css文件引用的背景图片地址 可以全…...
ollama导入huggingface下载的大模型并量化
1. 导入GGUF 类型的模型 1.1 先在huggingface 下载需要ollama部署的大模型 1.2 编写modelfile 在ollama 里面输入 ollama show --modelfile <你有的模型名称> eg: ollama show --modelfile qwen2.5:latest修改其中的from 路径为自己的模型下载路径 FROM /Users/lzx/A…...
Java 集合 Map Stream流
目录 集合遍历for each map案例 编辑 这种数组的遍历是【index】编辑map排序【对象里重写compareTo编辑map排序【匿名内部类lambda编辑 stream流编辑 编辑获取: map的键是set集合,获取方法map.keySet() map的值是collection 集合&…...
记录一下零零散散的的东西-ImageNet
ImageNet 是一个非常著名的大型图像识别数据集, 数据集基本信息 内容说明📸 图像数量超过 1400万张图片(包含各类子集)🏷️ 类别数量常用的是 ImageNet-1K(1000类)🧑Ἶ…...
【网络安全实验】PKI(证书服务)配置实验
目录 一、PKI相关概念 1.1 定义与核心功能 1.2 PKI 系统的组成 1.证书颁发机构(CA, Certificate Authority) 2.注册机构(RA, Registration Authority) 3.数字证书 1.3 PKI 的功能 1.4 PKI认证体系: 工作流程 …...
【数据集】多视图文本数据集
多视图文本数据集指的是包含多个不同类型或来源的信息的文本数据集。不同视图可以来源于不同的数据模式(如原始文本、元数据、网络结构等),或者不同的文本表示方法(如 TF-IDF、词嵌入、主题分布等)。这些数据集常用于多…...
学透Spring Boot — 007. 七种配置方式及优先级
Spring Boot 提供很多种方式来加载配置,本文我们会用Tomcat的端口号作为例子,演示Spring Boot 常见的配置方式。 几种配置方式 使用默认配置 新建一个项目什么都不配置,Spring Boot会自动配置Tomcat端口号。 启动日志 TomcatWebServer :…...
元素定位-xpath
xpath其实就是一个path(路径),一个描述页面元素位置信息的路径,相当于元素的坐标xpath基于XML文档树状结构,是XML路径语言,用来查询xml文档中的节点。 绝对定位 从根开始找--/(根目录)/html/body/div[2]/div/form/div[5]/button缺…...
【youcans论文精读】弱监督深度检测网络(Weakly Supervised Deep Detection Networks)
欢迎关注『youcans论文精读』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans论文精读】弱监督深度检测网络 WSDDN 0. 弱监督检测的开山之作0.1 论文简介0.2 WSDNN 的步骤0.3 摘要 1. 引言2. 相关工作3. 方法3.1 预训练网络3.2 弱监督深度检测网络3.3 WSDDN训练3.4 空间…...
网络购物谨慎使用手机免密支付功能
在数字经济蓬勃发展的当下,“免密支付”成为许多人消费时的首选支付方式。 “免密支付”的存在有其合理性。在快节奏的现代生活中,时间愈发珍贵,每节省一秒都可能带来更高的效率。以日常通勤为例,上班族乘坐交通工具时,…...
Sentinel[超详细讲解]-4
🚓 主要讲解流控模式的 三种方式中的两种: 直接、链路🚀 1️⃣ 直接模式 🚎 直接模式:对资源本身进行限流,例如对某个接口进行限流,当该接口的访问频率超过设定的阈值时,直接拒绝新的…...
【服务日志链路追踪】
MDCInheritableThreadLocal和spring cloud sleuth 在微服务架构中,日志链路追踪(Logback Distributed Tracing) 是一个关键需求,主要用于跟踪请求在不同服务间的调用链路,便于排查问题。常见的实现方案有两种&#x…...
【行测】判断推理:图形推理
> 作者:დ旧言~ > 座右铭:读不在三更五鼓,功只怕一曝十寒。 > 目标:掌握 图形推理 基本题型,并能运用到例题中。 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安! …...
OpenCV 图形API(12)用于计算图像或矩阵的平均值函数mean()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 计算矩阵元素的平均值(均值)。 mean函数计算矩阵元素的平均值M,每个通道独立计算,并返回该值。 …...
Oracle触发器使用(一):DML触发器
Oracle触发器使用(一):DML触发器 DML触发器条件谓词触发器INSTEAD OF DML触发器复合DML触发器Oracle数据库中的触发器(Trigger)本质上也是PL/SQL代码,触发器可以被Enable或者Disable,但是不能像存储过程那样被直接调用执行。 触发器不能独立存在,而是定义在表、视图、…...
3D模型给可视化大屏带来了哪些创新,都涉及到哪些技术栈。
一、3D 模型给可视化大屏带来的创新 更直观的视觉体验 传统的可视化大屏主要以二维图表和图形的形式展示数据,虽然能够传达一定的信息,但对于复杂的场景和数据关系,往往难以直观地呈现。而 3D 模型可以将数据以三维立体的形式展示出来&#…...
Unity HDRP管线用ShaderGraph还原Lit,方便做拓展;
里面唯一的重点就是判断有无这张复合图,我用的是颜色判断: float Tex TexCol.r*TexCol.g*TexCol.b*TexCol.a; if(Tex 1) { IsOrNot 1; } else { IsOrNot 0; } 其他的正常解码就行,对了法线贴图孔位记得设置成normal,不然的话…...
绝缘升级 安全无忧 金能电力环保绝缘胶垫打造电力安全防护新标杆
在电力安全领域,一块看似普通的胶垫,却是守护工作人员生命安全的“第一道防线”。近年来,随着电网设备升级和环保要求趋严,传统绝缘胶垫有异味、易老化、绝缘性能不足等问题逐渐暴露。为此,金能电力凭借技术创新推出新…...
Linux命令-iotop
iotop 命令 iotop 是一个用于实时监控磁盘 I/O 活动的工具,可以显示哪些进程正在使用磁盘资源。 参数 描述 –version 显示程序版本号并退出 -h, --help 显示此帮助消息并退出 -o, --only 仅显示实际进行 I/O 操作的进程或线程 -b, --batch 非交互模式,适…...
记录 | Android getWindow().getDecorView().setSystemUiVisibility(...)设置状态栏属性
纯纯的一边开发一边学习,是小白是菜鸟,单纯的记录和学习,大神勿喷,理解有错望指正~ getWindow().getDecorView().setSystemUiVisibility(…) 该方法用于控制系统 UI(如状态栏、导航栏)的可见性…...
QTableWidget 中insertRow(0)(头插)和 insertRow(rowCount())(尾插)的性能差异
一、目的 在 Qt 的 QTableWidget 中,insertRow(0) (头插)和 insertRow(rowCount())(尾插)在性能上存在显著差异。 二、QAbstractItemModel:: insertRows 原文解释 QAbstractItemModel Class | Qt Core 5.15.18 AI 解…...
用nodejs连接mongodb数据库对标题和内容的全文本搜索,mogogdb对文档的全文本索引的设置以及用node-rs/jieba对标题和内容的分词
//首先我们要在Nodejs中安装 我们的分词库node-rs/jieba,这个分词不像jieba安装时会踩非常多的雷,而且一半的机率都是安装失败,node-rs/jieba比jieba库要快20-30%;安装分词库是为了更好达到搜索的效果 这个库直接npm install node-rs/jieba即…...
【万字总结】前端全方位性能优化指南(完结篇)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前言 自适应进化宣言 当监控网络精准定位病灶,真正的挑战浮出水面:系统能否像生物般自主进化? 五维感知——通过设备传感器实时捕获环境指纹(如地铁隧道弱光环境自动切换省电渲染) 基因调参——150个性能参数在遗传算…...
不绕弯地解决文件编码问题,锟斤拷烫烫烫
安装python对应库 pip install chardet 检测文件编码 import chardet# 检测文件编码 file_path rC:\Users\AA\Desktop\log.log # 这里放文件和文件绝对路径 with open(file_path, rb) as f:raw_data f.read(100000) # 读取前10000个字节result chardet.detect(raw_data)e…...
高密度任务下的挑战与破局:数字样机助力火箭发射提效提质
2025年4月1日12时,在酒泉卫星发射中心,长征二号丁运载火箭顺利升空,成功将一颗卫星互联网技术试验卫星送入预定轨道,发射任务圆满完成。这是长征二号丁火箭的第97次发射,也是长征系列火箭的第567次发射。 执行本次任务…...
