当前位置: 首页 > news >正文

数论 欧拉线性素数筛

简述  

  素数筛是数论的门票(签到工具)

  很多数论问题都需要用到素数筛。

  本文将从作者自己的角度去阐述怎么写出欧拉线性筛。

素数筛的原理:

   必定有一个 不小于所有质因数   (  ≤  )  的质因数b 与 一个  大于等于所有因数   (  ≥  )  的因数c ( c ≠ 1) 乘积等于 合数a 

  本文 最小 是 不小于等于 的意思

   a = b * c ( a为合数,b 为 最小质因数 的质因数, c 为因数, 但 c 不等于 1 )

  至于为什么?

  因为

    假设 a ≠ 1,b 是质因数,c是因数,但 c 不等于 1

    a = b * c  

  那么,

    c = d * e,b,c,e中有一个 最小质因数 的 质因数。

  那么,

    假设是 e.是最小质因数

    a =  ( b * d ) * e ,

  因为

     d ≥ e 

     那么 ( b * d ) 构成了一个≥ c 的因数

  例如

    12 = 3*4 = 3 * 2 * 2= 2*6 , 那么最小质因数就是2,6 是 > 3,2,1 的因数。

    我们就需要 枚举这个 ≥ 每个因数 的数 去筛出合数,也就是确保每个合数被最小的质因数筛去

代码:

  实现细节: 

    要 求出 【2,n】的质数,

    1. 先从 小到大 枚举数 2~n 。

    (为什么要枚举到n ? 因为 n 可能为质数)

     ( 为什么从小到大枚举? 为了找出筛去合数的最小质因数)

     ( 为什么不会筛掉质数? 如果是枚举的数是质数,因为质数 = 1 * 最小质因数, 我们从 2开始枚举,肯定不会筛到质数,

     ( 为什么可以保证,n以内的合数肯定被筛去.? 每个合数被最小质因数筛去,也就是每个合数 大于等于所有因数的因数 已经被枚举过, 到了n,就自然只有 n * 最小质因数 = Y 这个值没有被筛了,虽然Y可能为质数...... )

    ( 我还有问题!为什么不会合数不会被重复筛!!! 因为我们可以确保每个合数只被他的最小质因数筛去。确保外层枚举的因数 >= 每个因数 

    2. 然后用 因数 乘上 对应的最小质因数  去找出 要筛掉的合数。

    3. 我们需要判断一下筛掉的 合数 的有没有超过 n 的范围。

    4. 同时需要保证,我们是用最小质因数筛掉这个合数的( 确保外层枚举的因数 >= 每个因数 ),这样就避免了重复筛。

    怎么保证?

         因为外层循环枚举因数,要确保每个合数是被最小质因数筛去,那么就得 确保外层枚举的因数 >= 每个因数 。

         a = b * c = d * e , c如果是最小质因数,那么 b ≥ d , e 。我们外层循环的 i 就得是 这个 b

         例如:如果 i % prime[j] == 0 ,那么 i == k * prime[j] ,  如果继续循环 j++ , 

         下个要筛的合数就是  i * prime[j+1] == k * prime[j+1] * prime[j] ( prime[j+1] > prime[j] )

         因为我们现在外层枚举的数是 i == k * prime[j] , 而当外层枚举的是 k * prime[j + 1]  才能去筛去。

         不用继续筛后面的数了,跳出循环,继续枚举因数。

那么 可以码出。

const int MAXN = 10000000;
int n,m;
int prime[MAXN];//保存质数
bool istPrime[MAXN];//不是质数
int cnt;

void sPrime(int n){
    istPrime[1] = true;
    for(int i = 2;i <= n; ++i){ //枚举大于与等于每个因数的因数
        if(!istPrime[i])
            prime[cnt++] = i; 
        for(int j=0;j<cnt && i*prime[j] <= n;j++){ //枚举最小质因数
            istPrime[i*prime[j]] = true;  //筛掉合数
            if(i%prime[j] == 0){ // 确保外层枚举的因数 >= 每个因数
                break; 
            }
        }
    }
}

 

推荐题目:

  https://www.luogu.org/problemnew/show/P3383

转载于:https://www.cnblogs.com/--zz/p/10519322.html

相关文章:

  • lync server 2013边缘前端无法同步
  • 专业PPT制作 驼峰设计
  • P4720 【模板】扩展卢卡斯
  • Linux 遭入侵,挖矿进程被隐藏排查记录
  • 血淋淋的BUG:波音在软件开发上错在哪里?
  • Python安装常见问题(1):zipimport.ZipImportError: can't decompress data
  • 当今软件发展的现状非常适合 Cloud Native 环境
  • Leetcode PHP题解--D8 832. Flipping an Image
  • Aspx 网页跳转方法 摘要一个大佬的自用
  • 四、RabbitMQ3.7在CentOS7下的安装
  • SpringCloud SpringBoot mybatis分布式微服务云架构返回JSON格式
  • node.js学习笔记
  • leetCode笔记--(1)
  • 致学习java同学奔三的90后:蹦最嗨的深夜迪,喝着啤酒配枸杞。
  • Exchange 2010/2016服务器远程重启命令
  • (三)从jvm层面了解线程的启动和停止
  • Electron入门介绍
  • go语言学习初探(一)
  • Java反射-动态类加载和重新加载
  • PAT A1120
  • PHP CLI应用的调试原理
  • PHP 的 SAPI 是个什么东西
  • php的插入排序,通过双层for循环
  • quasar-framework cnodejs社区
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • scala基础语法(二)
  • Windows Containers 大冒险: 容器网络
  • windows下如何用phpstorm同步测试服务器
  • 两列自适应布局方案整理
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 前端相关框架总和
  • 使用Swoole加速Laravel(正式环境中)
  • 怎么把视频里的音乐提取出来
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • # 透过事物看本质的能力怎么培养?
  • #pragma once与条件编译
  • #stm32驱动外设模块总结w5500模块
  • #控制台大学课堂点名问题_课堂随机点名
  • $.ajax()
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (ibm)Java 语言的 XPath API
  • (阿里云万网)-域名注册购买实名流程
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (论文阅读11/100)Fast R-CNN
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (万字长文)Spring的核心知识尽揽其中
  • (转)VC++中ondraw在什么时候调用的
  • (转)负载均衡,回话保持,cookie
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .net Application的目录
  • .net CHARTING图表控件下载地址
  • .NET Core 成都线下面基会拉开序幕
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道