一般的线性筛法

genPrime和genPrime2是筛法求素数的两种实现,一个思路,表示方法不同而已。

#include<iostream>
#include<math.h>
#include<stdlib.h>
using namespace std;
const int MAXV = ; //素数表范围
bool flag[MAXV+]; //标志一个数是否为素数
int prime[MAXV+]; //素数表,下标从0开始
int size=; //素数个数
void genPrime(int max)
{
memset(flag, true, sizeof(flag));//首先对标签数组进行初始化,全部设为true。
for(int i = ; i <= max / ; i++)
{
/*
从2开始,删除2的倍数
*/
if(flag[i])
{
//j=i<<1等价于 j=i*2,即j是i的两倍,而最后的j+=i,则表示下一个循环j是i的3倍,接着4倍。。。
//i的所有2~N倍数肯定都不是素数,因此将flag置为0,直到最后一位。
for(int j = i << ; j <= max; j += i)
{
flag[j] = false;
}
}
}
for(int i = ; i <= max; i++)
{
if(flag[i])
{
prime[size++] = i;//存储素数。将所有标志位依然为1的标志写入素数数组中去。
}
}
}
void genPrime2(int max)
{
memset(flag, true, sizeof(flag));//首先对标签数组进行初始化,全部设为true。
int sq=sqrt((double)max)+; //一个数 n 如果是合数,那么它的所有的因子不超过sqrt(n)
int i,j, k;
for(i = ;i<=sq; i++)
{
if(flag[i])
for(j=,k=max/i+;j<k;j++)
flag[i*j] = false; //所有i的j倍都不是素数
}
for( i = ; i <= max; i++)
{
if(flag[i])
{
prime[size++] = i;//存储素数。将所有标志位依然为1的标志写入素数数组中去。
}
}
}

int main()
{
// genPrime(MAXV);
genPrime2(MAXV);
//输出所有素数。
for(int i=;i<size;i++)
cout<<prime[i]<<" ";
cout<<endl;
system("pause");
return ;
}
/*
3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
请按任意键继续. . .
*/

快速线性筛法

快速线性筛法没有冗余,不会重复筛除一个数,所以“几乎”是线性的。

#include<iostream>
using namespace std;

const long N = ;
long prime[N] = {},num_prime = ;
int isNotPrime[N] = {, };
int main()
{
for(long i = ; i < N ; i ++)
{
if(! isNotPrime[i])
prime[num_prime ++]=i;
//关键处1
for(long j = ; j < num_prime && i * prime[j] < N ; j ++)
{
isNotPrime[i * prime[j]] = ;
if( !(i % prime[j] ) ) //关键处2
  break;
}
}
return ;
}

首先,先明确一个条件,任何合数都能表示成一系列素数的积。

不管 i 是否是素数,都会执行到“关键处1”,

  ①如果 i 都是是素数的话,那简单,一个大的素数 i 乘以不大于 i 的素数,这样筛除的数跟之前的是不会重复的。筛出的数都是 N=p1*p2的形式, p1,p2之间不相等

  ②如果 i 是合数,此时 i 可以表示成递增素数相乘 i=p1*p2*...*pn, pi都是素数(2<=i<=n),  pi<=pj  ( i<=j ),p1是最小的系数。

根据“关键处2”的定义,当p1==prime[j] 的时候,筛除就终止了,也就是说,只能筛出不大于p1的质数*i。

直观地举个例子。i=2*3*5

此时能筛除 2*i ,不能筛除 3*i

如果能筛除3*i 的话,当 i' 等于 i'=3*3*5 时,筛除2*i' 就和前面重复了。

Algorithm --> 筛法求素数的更多相关文章

  1. 初等数论-Base-1(筛法求素数,欧拉函数,欧几里得算法)

    前言 初等数论在OI中应用的基础部分,同机房的AuSquare和zhou2003君早就写完了,一直划水偷懒的Hk-pls表示很方,这才开始了这篇博客. \(P.S.\)可能会分部分发表. Base-1 ...

  2. 蓝桥杯 算法训练 Torry的困惑(基本型)(水题,筛法求素数)

    算法训练 Torry的困惑(基本型) 时间限制:1.0s   内存限制:512.0MB      问题描述 Torry从小喜爱数学.一天,老师告诉他,像2.3.5.7……这样的数叫做质数.Torry突 ...

  3. hdu 4548 筛法求素数 打表

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4548 Problem Description 小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题 ...

  4. UVA 10006 - Carmichael Numbers 数论(快速幂取模 + 筛法求素数)

      Carmichael Numbers  An important topic nowadays in computer science is cryptography. Some people e ...

  5. 筛法求素数Java

    输出:一个集合S,表示1~n以内所有的素数 import java.util.Scanner; public class 筛法求素数 { public static void main(String[ ...

  6. JD 题目1040:Prime Number (筛法求素数)

    OJ题目:click here~~ 题目分析:输出第k个素数 贴这么简单的题目,目的不清纯 用筛法求素数的基本思想是:把从1開始的.某一范围内的正整数从小到大顺序排列, 1不是素数,首先把它筛掉.剩下 ...

  7. 2018牛客网暑期ACM多校训练营(第三场) H - Diff-prime Pairs - [欧拉筛法求素数]

    题目链接:https://www.nowcoder.com/acm/contest/141/H 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...

  8. 埃氏筛法求素数&构造素数表求素数

    埃氏筛法求素数和构造素数表求素数是一个道理. 首先,列出从2开始的所有自然数,构造一个序列: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1 ...

  9. <转载>一般筛法和快速线性筛法求素数

    素数总是一个比较常涉及到的内容,掌握求素数的方法是一项基本功. 基本原则就是题目如果只需要判断少量数字是否为素数,直接枚举因子2 ..N^(0.5) ,看看能否整除N. 如果需要判断的次数较多,则先用 ...

随机推荐

  1. 一句Python,一句R︱数据的合并、分组、排序、翻转

    先学了R,最近刚刚上手python,所以想着将python和R结合起来互相对比来更好理解python.最好就是一句python,对应写一句R. python中的numpy模块相当于R中的matirx矩 ...

  2. PCI9054 学习小结

    PCI的基本协议这里就不介绍了,因为一般的芯片协议都是集成好的,我只需要大体了解就行,不需要做芯片,我感觉就不需要太了解协议. 这里讲解是基于PLX 的9054(9052)芯片为基础的,本人只是入门, ...

  3. BFS-九宫格重排(详解)

    BFS将近两年没练过题了,今天重新回忆下以前刷的蓝桥杯题:九宫格重排 样例输入  //初始状态 //终点状态 样例输出  //最短步数 样例输入  //初始状态 //终点状态 样例输出  //最短步数 ...

  4. C#图解教程

    初识本书是在知乎,许多网友推荐它作为 C# 入门书籍. 本书的最大特点是插图丰富,许多复杂的概念,一副插图就解释得通透明了. 本书另外一个隐藏特性是作者有着 C/C++ 经验,书中经常提到它们与 C# ...

  5. C# 图解教程 第三章 类型、存储和变量

    类型.存储和变量 C#程序是一组类型声明类型是一种模板实例化类型数据成员和函数成员预定义类类型用户定义类型栈和堆 栈堆 值类型和引用类型 存储引用类型对象的成员C#类型的分类 变量静态类型和dynam ...

  6. n人围成一圈报数

    题目:有n个人围成一圈,顺序排号.从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位 思路:用一个数组存这n个人,里面的初始状态全设为1,表示都还在圈子里面. ...

  7. lvs-dr 模式-piranha

    系统: redhat 6.5 mini 机器名 ip vip lvs01(主lvs) 192.168.20.10 192.168.20.254 lvs02(备lvs) 192.168.20.20 rs ...

  8. linux用户和群组

    1.用户的主要群组和次要群组   切换用户:su -username 查看群组:#vi /etc/passwd         //主要群组                  #vi /etc/gro ...

  9. 【BZOJ4698】Sandy的卡片(后缀数组)

    [BZOJ4698]Sandy的卡片(后缀数组) 题面 讨厌权限题!!! 因为我交不了... 洛谷 题面 做完差之后就是裸的最长公共子串 没了.. 数组往死里开吧... #include<ios ...

  10. angular 按下回车键触发事件

    angularJs  按下回车键触发事件这个功能很简单,但是今天的却让我掉坑很久.... 由于我的页面上有两个不同方法都传$event事件,如search($event)和create($event) ...