Date:2019/10/16??
其实现在都快1点了,算是16号,啊??
今天讲了素数的筛法

其实,在很小的数据范围内,不同的算法复杂度是差不多的,但是,如果处理几个数据,算法的作用就没有发挥出来

  1. 朴素算法
  2. 埃氏筛法
  3. 线性筛法(欧拉筛)
  4. P3383 【模板】线性筛素数

朴素算法

素数最朴素的算法了
它的时间复杂度是O(n*sqrt(n))

bool prime (int x){for(int i = 2; i <= x; i ++){if(x % i ==0){return 0;}}return 1;
}

但是,这只适用于小数据的处理,所以我们需要改进算法

Eratosthenes(埃氏筛法)

  • 整数的唯一分解定理:
    任何一个大于1的自然数 N,如果N不为质数,都可以唯一分解成有限个质数的乘积N=P1 ^ a1 · P2 ^ a2 · P3 ^ a3 · … · Pn ^ an ,这里P1<P2<P3<…<Pn均为质数,其诸指数 ai 是正整数。
    (:当然质数的话直接就是质数本身)

  • 埃氏筛法的思想:
    枚举每个素数,然后把他们的倍数都打上标记,从而达到筛出的目的
    质数的倍数一定不是质数

时间复杂度是 O(nloglogn)

具体代码是
  • 注意j = i可以做到一部分的优化作用
for(int i = 1; i <= sqrt(n); i ++){       //循环一遍可以有倍数的    if(b[i] == 1) continue;           //如果不是质数或已经判断过,直接跳过 for(int j = i; i * j <= n;j++){       //内层循环倍数 //pay attention to j = i; b[i*j] = 1;                        //打上标记                  }
}

但是这个算法在1e7左右还是不太好用,会TLE(~~哭晕~
而且埃氏筛法还有一个缺陷 :
对于一个合数,有可能被筛多次。例如 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++) {if (!visit[i]) {prime[++prime[0]] = i;      //记录素数, 这个prime[0] 相当于 cnt,用来计数}for (int j = 1; j <= prime[0] && i*prime[j] <= maxn; j++) {//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) { //这一步比较重要,如果i%j==0,说明i 就不是最小的质因子,所以就跳出程序了;break;}}}
}
  • 还有网友版本的~
void init()
{memset(bz,1,sizeof(bz));tot=0;for (int i=2;i<MAXN;i++) {if (bz[i])p[tot++]=i;for (int j=0;j<tot && i*p[j]<=MAXN;j++) {bz[i*p[j]]=0;if (i%p[j]==0)break;}}
}
————————————————
版权声明:本文为CSDN博主「路人黑的纸巾」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/enjoy_pascal/article/details/80372454

涨知识ing~~~
%%%%%%dalao 们

P3383 【模板】线性筛素数

做个水题
P3383 【模板】线性筛素数

裸题

AC code

  • 稍微注意一下0和1的特判
//Author:PhilFan;
#include<bits/stdc++.h>
#define MAXN 10000010
using namespace std;
int n,m,a[MAXN],p[MAXN],x;
void init(int n)
{memset(p,0,sizeof(p));p[1]=1;  tot=0;for (int i = 2;i <= n;i++) {if(a[i]==0)    p[tot++]= i;for (int j = 0;j < tot && i * p[j] <= n+5; j++) {a[i * p[j]] = 1;if (i % p[j] == 0)    break;}}
}int main()
{scanf("%d %d",&n,&m);init(n);a[0]=1,a[1]=1;for(int i = 1; i <= m; i++){scanf("%d",&x);if(a[x]==0){printf("Yes\n");}else{printf("No\n");}x=0;}  return 0;
}

P1865 A % B Problem网址

这道题是输出区间的质数,需要在线性筛法中加入一个前缀和的数组,因为不加的话会TLE一个点


//Author:PhilFan;
#include<bits/stdc++.h>
#define MAXN 10000010
using namespace std;
int n,m,a[MAXN],p[MAXN],b[MAXN],x,y,cnt;
void init(int n)
{memset(p,0,sizeof(p));p[1]=1;  int tot=0;for (int i = 2;i <= n;i++) {if(a[i]==0){p[tot++]= i;b[i]=b[i-1]+1;//前缀和数组   //如果有多的质数,数组++}else b[i]=b[i-1];//如果质数没有多,b[i]就和上一个一样for (int j = 0;j < tot && i * p[j] <= n+5; j++) {a[i * p[j]] = 1;if (i % p[j] == 0)   break;}}
}int main()
{scanf("%d %d",&m,&n);a[0]=1,a[1]=1;init(n);for(int i = 1; i <= m; i++){scanf("%d %d",&x,&y);if(x<1||x>n||y<1||y>n){       //特判printf("Crossing the line\n");}else{cout<<b[y]-b[x-1]<<endl;  //x有可能也是质数,所以是x-1x = 0 , y = 0;}}  return 0;
}

[数学/质数筛] 素数筛法相关推荐

  1. P1217 [USACO1.5]回文质数 Prime Palindromes(素数筛法/打表)

    P1217 [USACO1.5]回文质数 Prime Palindromes(素数筛法/打表) 一:埃氏筛(时间复杂度--nloglogn) 重点:一个数x是合数,则它的倍数也是合数 //用埃氏筛生成 ...

  2. c语言 快速筛质数,快速筛素数(埃式筛+线性筛+Miller_Rabin算法)

    在CF上做到一道核心是需要筛出1~n所有素数的题目,然后刚好又没学过,就学习了快速筛素数的办法,基础的n根号n的算法这里大家每个人都知道吧QAQ,就不讲了,好像还是C语言上机说过的题目. 首先给大家介 ...

  3. 素数筛法详解:埃氏筛和欧拉筛

    文章目录 摘要 埃式筛 欧拉筛 超级详细的基础算法和数据结构合集: https://blog.csdn.net/GD_ONE/article/details/104061907 摘要 本文主要介绍埃氏 ...

  4. 素数筛法(传统普通、朴素筛法、埃式筛法、欧拉筛法(线性筛))

    素数筛法(普通.朴素筛法.埃式筛法.欧拉筛法) 1.题目 2.分析 3.代码 传统普通 朴素筛法 朴素筛法(6.14) 埃式筛法 埃式筛法(6.14) 欧拉筛法(线性筛) 欧拉筛法(线性筛 6.14) ...

  5. 质数||素数(分解质因数、筛素数、质数定理)

    质数又称素数.一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数,否则称为合数. 规定1既不是质数也不是合数 分解质因数:把一个合数分解成若干个因数乘积的形式 分解质因数(也称分解 ...

  6. 求质数(素数)算法,及算法优化

    质数(素数):只能被1和其本身整除的数字(其中1和0不属于质数) 接下来我们用多种方法求1000以内(包含1000)的质数数量,并且统计每种方法的循环次数 (如果只想知道速度快的方法可以直接看方法五) ...

  7. 普通素数 筛法求素数 二次筛法求素数 MillerRabin素数测试【模板】

    素数和合数共同的性质: 1.a > 1是合数,当且仅当a = b * c,其中1 < b < a,1 < c < a. 2.合数必有素数因子. 3.如果d > 1, ...

  8. C语言:素数筛法与分解素因数

    一.素数筛法 素数筛法是关于求小于某个大数(正整数)的所有素数的算法,首先有理论:任何整数n≥2都可以分解成若干质数的乘积,即n=p1p2···pr. 用筛法求素数的基本思想是:把从1开始的.某一范围 ...

  9. 线性筛法求素数c语言,[算法]素数筛法(埃氏筛法线性筛法)

    一.素数筛的定义 给定一个整数n,求出[1,n]之间的所有质数(素数),这样的问题为素数筛(素数的筛选问题). 二.埃氏筛法(Eratosthenes筛法) 埃氏筛法又叫做Eratosthenes筛法 ...

最新文章

  1. 从一个数组中寻找出现奇数次的数字
  2. 微星网卡linux驱动,微星中国
  3. 01-JDBC概念--JDBC(Java Database Connectivity:Java数据库连接):使用jdbc实现Java与数据库MySQL连接
  4. 【干货】什么是好的社交产品
  5. curl 请求没反应_理解Redis的反应堆模式
  6. opengl es 实现旋转的三角形
  7. android r 编译找不到头文件_嵌入式开发之交叉编译程序万能命令_以freetype为例...
  8. Mybatis 实现关联表查询
  9. html怎么置顶图像,css怎么固定图片位置不变?
  10. idea 中 maven 项目依赖关系 查看 箭头的含义
  11. 大数据IMF传奇行动绝密课程第91课:SparkStreaming基于Kafka Direct案例实战和内幕源码解密
  12. QLV转MP4格式转换器在线免费的方法有哪些
  13. 逆时针旋转某一角度的旋转矩阵
  14. 利用kettle获取企业微信打卡数据
  15. Linux服务篇--LAMP架构
  16. 【论文泛读85】基于上下文的句子相似度
  17. 请收下这份秘籍: 这里有关于申请 gTech 职位所需知道的一切
  18. 我的气垫船充满了鳗鱼
  19. FMDB - - 归纳整理- Vic_Li
  20. 北京第一年-OpenGL-19-沉淀

热门文章

  1. 英语单词: entropy;熵
  2. [静态时序分析简明教程(三)]备战秋招,如何看懂一个陌生的timing report
  3. 安装BT5 backtrack5 linux 无线网卡驱动
  4. android仿微信拍摄视频教程,仿微信视频拍摄UI, 基于ffmpeg的视频录制编辑(上)
  5. 怎样连接网站的服务器ipad,ipad可以连接云服务器地址
  6. 苹果系统计算机常用英语,iOS开发必备英语词汇整理
  7. flash 嵌入html代码,flash嵌入html在html网页代码中嵌入Flash文件的解决方案(下).doc...
  8. 基于Git子模块的微前端项目管理和公用组件库方案
  9. 格签名相似概念区分: SVP、SIS、LWE的区分
  10. ADN FDN SDN