线性筛选(埃拉托斯特尼筛法升级版欧拉筛法)

原理:

任何一个合数都可以表示成一个质数和一个数的乘积

假设A是一个合数,且A = x * y,这里x也是一个合数,那么有:

A = x * y; (假设y是质数,x合数)

x = a * b; (假设a是质数,且a < x——>>a<y)

-> A = a b y = a Z (Z = b y)

即一个合数(x)与一个质数(y)的乘积可以表示成一个更大的合数(Z)与一个更小的质数(a)的乘积,那样我们到每一个数,都处理一次,这样处理的次数是很少的,因此可以在线性时间内得到解。

仍然按上面的例子模拟(这里0为是素数,1为非素数,p为记录的素数表):

初始:

1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

p(empty)

然后到2的位置,把2放入素数表,做当前范围内可以筛掉的处理(具体是怎样的看代码叭):

1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

p 2 到3,把3放入素数表,继续处理

1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0

p 2 3 然后到了4,它不是个素数,也处理一下

1 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0

p 2 3 .......

然后一直搞下去,最后也能得到完整的素数表,这样虽然看起来复杂一些,但是实际上我们发现对于每个数的处理几乎是O(1)的。

void get_list(){
for(int i=2;i<=maxn;i++){
  if(!isPri[i]) prime[++tot]=i;
  for(int j=1;j<=tot&&i*prime[j]<=maxn;j++){
    isPri[i*prime[j]]=1;
    if(i==j) break;
  }
}

原文地址:https://www.cnblogs.com/djf666/p/9367517.html

时间: 2024-10-10 22:01:34

线性筛选(埃拉托斯特尼筛法升级版欧拉筛法)的相关文章

利用OpenMP实现埃拉托斯特尼(Eratosthenes)素数筛法并行化

1.算法简介 1.1筛法起源 筛法是一种简单检定素数的算法.据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274-194年)发明的,又称埃拉托斯特尼筛法(sieve of Eratosthenes). 1.2筛法过程 具体做法是:给出要筛数值的范围 n,找出 n√以内的素数p1,p2,p3,--,pk.从最小素数2去筛,即把2留下,把2的倍数剔除掉:再用下一个素数,也就是3筛,把3留下,把3的倍数剔除掉:接下去用下一个素数5筛,把5留下,把5的倍数剔除掉:不断重复下去. 2.实现

线性筛法(欧拉筛法)求素数

时间复杂度O(n)当n比较大时欧拉筛法所用的时间比O(nloglogn)的算法的时间少的会越来越明显 为什么呢? 因为在欧拉筛法中,每一个合数只被访问并将其所对的f[]的值修改了一次. for(i = 2; i <= n; i++) { if(f[i] == 0) { p[++cnt] = i; } for(j = 1; j <= cnt; j++) { if(i * p[j] > n)break; f[i * p[j]] = 1; if(i % p[j] == 0)break; } }

数论部分第二节:埃拉托斯特尼筛法

埃拉托斯特尼筛法 质数又称素数.指在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数.怎么判断n以内的哪些数是质数呢? 埃拉托斯特尼筛法 厄拉多塞是一位古希腊数学家,他在寻找素数时,采用了一种与众不同的方法:先将2-N的各数放入表中,然后在2的上面画一个圆圈,然后划去2的其他倍数:第一个既未画圈又没有被划去的数是3,将它画圈,再划去3的其他倍数:现在既未画圈又没有被划去的第一个数是5,将它画圈,并划去5的其他倍数……依次类推,一直到所有小于或等于N的各数都画了圈或划去为止.这

埃拉托斯特尼素数筛法

1 //埃拉托斯特尼筛法 2  3 int prime[maxx]; 4 bool is_prime[maxx+1];//is_prime[i]为true表示i为素数 5  6 //返回n以内素数的个数 7 int sieve (int n) 8 { 9     int p=0;10     for(int i=0; i<=n; i++) is_prime[i]=1;11     //memset(is_prime,1,sizeof(is_prime));12     is_prime[0]=i

[java]埃拉托斯特尼筛法检定素数

埃拉托斯特尼筛法,简称埃氏筛或爱氏筛,是一种由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法.要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的倍数剔除,剩下的就是素数. 要得到自然数n以内的全部素数,必须把不大于 的所有素数的倍数剔除,剩下的就是素数. 给出要筛数值的范围n,找出以内的素数.先用2去筛,即把2留下,把2的倍数剔除掉:再用下一个质数,也就是3筛,把3留下,把3的倍数剔除掉:接下去用下一个质数5筛,把5留下,把5的倍数剔除掉:不断重复下去....... java源码

生成素数序列----埃拉托斯特尼筛法

下面是埃拉托斯特尼筛法的实现代码: boolean[] sieveOfEratosthenes(int max) { boolean[] flags = new boolean[max + 1]; int count = 0; init(flags);//将flags中0,1元素除外的所有元素设为true int prime = 2; while (prime <= max) { //划掉余下为prime倍数的数字 crossOff(flags, prime); //找出下一个为true的值 p

『素数(Prime)判定和线性欧拉筛法(The sieve of Euler)』

素数(Prime)及判定 定义 素数又称质数,一个大于1的自然数,除了1和它自身外,不能整除其他自然数的数叫做质数,否则称为合数. 1既不是素数也不是合数. 判定 如何判定一个数是否是素数呢?显然,我们可以枚举这个数的因数,如果存在除了它本身和1以外的因数,那么这个数就是素数. 在枚举时,有一个很简单的优化:一个合数\(n\)必有一个小于等于\(\sqrt{n}\)的因数. 证明如下: 假设一个合数\(n\)没有小于等于\(\sqrt{n}\)的因数. 由于\(n\)为合数,所以除了\(n\)与

欧拉筛法(线性筛)素数

#include<bits/stdc++.h> using namespace std; #define maxn 40 int prime[maxn]; int visit[maxn]; void Prime(){//埃氏筛法 memset(visit,0,sizeof(visit)); //初始化都是素数 visit[0] = visit[1] = 1; //0 和 1不是素数 for (int i = 2; i <= maxn; i++) { if (!visit[i]) { //

【 数学基础】【素数线性筛法--欧拉筛法模板】【普通筛法的优化】

质数(素数):指大于1的所有自然数中,除了1和自身,不能被其它自然数整除的数 合数:比1大,但不是素数的数称为合数,合数除了被1和自身整除,还能被其它数整除 质因数(素因数或质因子):能整除给定正整数的质数,除1以外,两个没有其它共同质因子的正整数称为互质 1和0既非素数又非合数 素数筛法原理:素数的倍数一定不是素数. 实现步骤:用一个boook数组对maxn内的所有数进行标记,1为合数,0为素数,book初始化为0是假设全部数都为素数,从第一个素数2开始,把2的倍数标记为1,然后继续下一轮 欧