欧拉筛(线性筛)算法分析

news/2025/9/17 16:45:50/文章来源:https://www.cnblogs.com/kkman2000/p/19097097

前言
对于寻找素数,第一时间想到的便是二重循环暴力查找,其复杂度O(n^2),通过循环中只判断到根号n可以优化一些,不过复杂度也达不到预期。在数论的学习中,我学到了埃氏筛法,O(nloglogn)的算法,而在一些数据范围达到1e7这样的题目中,也很难让人满意,于是我便学习了欧拉筛法,也即 O(n)的线性筛法。

埃氏筛法
埃氏筛法的基本思想 :从2开始,将每个质数的倍数都标记成合数,以达到筛选素数的目的。
代码 :

 


int visit[maxn];  
void Prime(){
    mem(visit,0);           //初始化都是素数
    visit[0] = visit[1] = 1;  //0 和 1不是素数
    for (int i = 2; i <= maxn; i++) {
        if (!visit[i]) {         //如果i是素数,让i的所有倍数都不是素数
            for (int j = i*i; j <= maxn; j += i) { 
                visit[j] = 1;
            }
        }
    }
 

 

这里有一个小优化,j 从 i * i 而不是从 i + i开始,因为 i*(2~ i-1)在 2~i-1时都已经被筛去,所以从i * i开始。

埃氏筛法的缺陷 :对于一个合数,有可能被筛多次。例如 30 = 2 * 15 = 3 * 10 = 5*6……那么如何确保每个合数只被筛选一次呢?我们只要用它的最小质因子来筛选即可,这便是欧拉筛法。
欧拉筛法
欧拉筛法的基本思想 :在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。
代码 :

int prime[maxn];
int visit[maxn];
void Prime(){
    mem(visit,0);
    mem(prime, 0);
    for (int i = 2;i <= maxn; i++) {
        cout<<" i = "<<i<<endl;
        if (!visit[i]) {
            prime[++prime[0]] = i;      //纪录素数, 这个prime[0] 相当于 cnt,用来计数
        }
        for (int j = 1; j <=prime[0] && i*prime[j] <= maxn; j++) {
//            cout<<"  j = "<<j<<" prime["<<j<<"]"<<" = "<<prime[j]<<" i*prime[j] = "<<i*prime[j]<<endl;
            visit[i*prime[j]] = 1;
            if (i % prime[j] == 0) {
                break;
            }
        }
    }
} 

对于visit[i*prime[j]] = 1 的解释: 这里不是用i的倍数来消去合数,而是把 prime里面纪录的素数,升序来当做要消去合数的最小素因子。
打表观察来理解 :

发现i在消去合数中的作用是当做倍数的。
对于 i%prime[j] == 0 就break的解释 :当 i是prime[j]的倍数时,i = kprime[j],如果继续运算 j+1,i * prime[j+1] = prime[j] * k prime[j+1],这里prime[j]是最小的素因子,当i = k * prime[j+1]时会重复,所以才跳出循环。
举个例子 :i = 8 ,j = 1,prime[j] = 2,如果不跳出循环,prime[j+1] = 3,8 * 3 = 2 * 4 * 3 = 2 * 12,在i = 12时会计算。因为欧拉筛法的原理便是通过最小素因子来消除。
结语
对于欧拉筛法的学习是先从接触到题开始的, 再次遇到题也不见得可以游刃有余的解决,在此与大家共勉,学海无涯。
附上题目 :https://nanti.jisuanke.com/t/30999 (大佬眼中的签到题) 

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

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

相关文章

2021年安徽省大数据与人工智能应用竞赛 大数据(网络赛)-高职组赛题

本套数据数据: 通过网盘分享的文件: 链接: https://pan.baidu.com/s/1ZQXoWQhCOAiGVcFOZozV1g?pwd=json 提取码: json 第二部分:大数据程序编写部分(30分) 任务一、数据抽取转化部分(5分) 1、使用sqoop将MySQL的sakila数据库中的city表中city列以C开头的数据导入到hdfs…

一些写了和没写的数学!

P8114 [Cnoi2021] 六边形战士 传送 非常好玩的题! 首先你大概率看过一些“无字证明”,其中很经典的是这个: 证明:用若干个边长为 \(1\),顶角为 \(60\) 度的菱形拼成一个边长为 \(n\) 的正六边形,三个方向的菱形个数一定相等。这是一个经典的无字证明,虽然前置的说明要费…

【光照】[自发光Emission]以UnityURP为例

【从UnityURP开始探索游戏渲染】专栏-直达自发光的基本原理 $Cemissive=Memissive$ 自发光是物体表面主动发射光线的现象,在光照模型中通常作为独立于外部光源的附加项。其核心特点是不受其他光照影响,但可以影响周围环境。 实现流程‌定义发射颜色和强度‌:确定基础发光颜色…

mybatis-plus初体验,解决报错Invalid value type for attribute factoryBeanObjectType: java.lang.String

解决报错Invalid value type for attribute factoryBeanObjectType: java.lang.String 推荐这位大佬的博客: https://www.cnblogs.com/muphy/p/18653627 项目结构MyBatis-Plus配置类MyBatisPlusConfig package com.example.config;import com.baomidou.mybatisplus.annotation…

Alexandresku设计的loki小对象内存分配器

Loki是由 Alexandresku 编写的一个与《Modern C++ Design》(C++设计新思维)一书配套发行的C++代码库。其中有两个文件 SmallObj.h 、SmallObj.cpp 进行内存管理,可以单独进行使用 三个class,第一层是chunk,第二层是vector<chunk> FixedAllocator,第三层是vector&l…

C++ 内存管理

C++ 内存管理是程序设计的核心环节,直接影响程序的性能、稳定性和安全性。C++ 不像 Java、Python 等语言有自动垃圾回收机制,而是需要开发者手动管理动态内存(或通过智能指针等机制自动管理)。 1、C++ 内存分区内存区域 存储内容 生命周期 管理方式栈 (Stack) 函数参数、局…

浅谈制氢电源及英飞凌解决方案

大家对氢元素肯定都不陌生,认识它基本都是从背元素周期表开始的。近年来我们身边多了很多氢的身影,从北京冬奥会的氢燃料电池大巴,再到广州南沙小虎岛电氢智慧能源站,氢也越来越被大家熟知。工业上,氢的使用可是一点都不少,自 1975 年以来,需求量增长了三倍,而且还在继…

微算法科技(NASDAQ:MLGO)研究分布式量子计算,释放量子计算潜能

在信息时代,数据量呈指数级增长,经典计算机面临算力瓶颈。量子计算以其超强的并行处理能力,被视为下一世代计算范式的颠覆者。然而,单个量子处理器的脆弱性和制造难度限制了其广泛应用。微算法科技(NASDAQ:MLGO)研发团队研究通过分布式量子计算模型,将多个量子计算节点连…

AI 重塑招聘三角:Moka 招聘智能体如何实现 HR、候选人与企业的三方共赢

AI 重塑招聘三角:Moka 招聘智能体如何实现 HR、候选人与企业的三方共赢在人才竞争进入白热化的今天,招聘早已不是 HR 单方面的 “筛选任务”,而是涉及 HR 效率、候选人体验、企业战略人才储备的三角关系。传统招聘模式下,这三角常常陷入 “HR 疲于奔命却难出成果、候选人等…

Flash Attention原理

提出问题 Transformer 结构已成为自然语言处理和图像分类等应用中最常用的架构。尽管 Transformer 在规模上不断增大和加深,但处理更长上下文仍然是一个挑战,因为核心的自注意力模块在序列长度上具有二次方的时间和内存复杂度。这导致在处理长序列时速度变慢且内存需求巨大。…

MSMQ 跨服务器读写队列的“消息队列系统的访问被拒绝”的解决方案

转:http://m.blog.csdn.net/blog/2000killer/8904852 在服务器上创建的Queue开发者的 机器只能写数据而不能读数据。.net给出的错误是“对消息队列系统的访问被拒绝”,也就是说拒绝访问队列没有相关权限,我给Everyone和 ANONYMOUS LOGON赋予全部权限都无法解决(正常情况下可…

Linux时间同步---NTP时间同步方案

1.方案背景: 在分布式系统或多服务器集群中,必须建立统一的时间同步机制。服务器间的时间不一致会破坏各类依赖时间交互逻辑,例如导致日志时序混乱、事务顺序错乱、证书验证失败等,从而引发一系列难以排查的不可预知故障。 2.NTP同步网络拓扑图: 3.同步方案 可提前咨询医…

java预习

课前问题列表 1.什么样的方法应该用static修饰?不用static修饰的方法往往具有什么特性?Student的getName应该用static修饰吗?适合用 static 修饰的方法: 工具类方法(如Math.abs())、工厂方法、不需要访问实例变量 / 方法的方法、单例模式的获取实例方法等,这类方法通常与…

B/S体系结构风格

三层B/S风格-概述 》浏览器/服务器(B/S)风格就是上述三层应用结构的一种实现方式,其具体结构为:浏览器/Web服务器/数据库服务器。 》B/S体系结构主要是利用不断成熟的WWW浏览技术,结合浏览的多种脚本语言,用通用浏览器就实现了原来需要复杂的专用软件才能实现的强大功能,…

The 2024 CCPC Online Contest 7/12 L/B/K/D/J/E/C

Problem L. 网络预选赛 签到,直接模拟即可点击查看代码 #include<bits/stdc++.h> using namespace std; int main(){int n,m;cin>>n>>m;vector<string>a(n);for(int i=0;i<n;i++){cin>>a[i];}int sum=0;for(int i=0;i<n-1;i++){for(int j…

在joule里面使用agent 功能

test: Dev: 1: structure 2: 本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究

Feign动态URL配置

方式一、亲测可用,缺点是每个类都需要单独配置@FeignClient(value = "my-biz", url = "${external.my.biz_url}", configuration = FeignHeaderInterceptor.class) public interface MyBizFeign {}@Data @Component @RefreshScope @ConfigurationProperti…

自动化部署工具 Jenkins 的安装与配置

Jenkins 是一个开源的自动化部署工具,广泛用于持续集成(CI)和持续交付(CD)流程。它支持自动化构建、测试和部署应用程序。以下是 Jenkins 的安装与配置的详细教程。1. 安装 Jenkins 以下步骤适用于 Linux 系统(以 Ubuntu 和 CentOS 为例),并包含安装必要的依赖环境。1.…

pip 搭建源

搭建本地pip源主要可通过pypiserver、pip2pi或bandersnatch等工具实现,具体步骤如下: 工具选择与安装‌pypiserver‌:轻量级方案,适合快速搭建小型私有源,通过pip install pypiserver安装 ‌pip2pi‌:适合按需构建源,从requirements.txt生成索引,需配合pip install pip…

qoj10093 Jump the Frog

题意 给出 \(n\) 个由 O 和 ~ 组成的字符串 \(s_i\),还有 \(m\) 个额外字符串,第 \(n+i\) 个字符串 \(s_{n+i}\) 由第 \(s_x\) 和 \(s_y\) \((x,y<n+i)\) 个字符串拼接得到,即 \(s_{n+i}=s_x+s_y\)。你需要对这 \(n+m\) 个字符串解决以下问题: 有一只青蛙从字符串的起点…