素数筛法(Eratosthenes筛法)

介绍

Eratosthenes筛法,又名埃氏筛法,对于求1~n区间内的素数,时间复杂度为n log n,对于10^6^ 以内的数比较合适,再超出此范围的就不建议用该方法了。
筛法的思想特别简单: 对于不超过n的每个非负整数p, 删除2p, 3p, 4p,…, 当处理完所有数之后, 还没有被删除的就是素数。

代码

void init()
{
    int cnt=0;
    for(int i=0;i <= Max;i++)
        is_prime[i] = true;
    is_prime[0]=is_prime[1]=false;
    for(int i=2;i<=Max;i++)
        if(is_prime[i])
        {
            prime[cnt++]=i;     //边筛边记录素数
            for(int j=2*i;j<=Max;j+=i)
                is_prime[j]=false;
        }
}

对应题目:Prime Gap UVA - 1644
对应题目代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n;
const int maxn = 100001, Max = 1299721;
int prime[maxn];
bool is_prime[Max+1];
void init()
{
    int cnt=0;
    for(int i=0;i <= Max;i++)
        is_prime[i] = true;
    is_prime[0]=is_prime[1]=false;
    for(int i=2;i<=Max;i++)
        if(is_prime[i])
        {
            prime[cnt++]=i;     //边筛边记录素数
            for(int j=2*i;j<=Max;j+=i)
                is_prime[j]=false;
        }
}
int main()
{
    std::ios::sync_with_stdio(false);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    init();
    while(cin >> n && n)
    {
        if(is_prime[n])
        {
            cout << 0 << endl;
            continue;
        }
        for(LL i = 0; i < maxn; i++)
        {
            if(prime[i] > n)
            {
                if(prime[i] != n)
                    cout <<  prime[i] - prime[i-1] << endl;
                break;
            }
        }
    }

}

原文地址:https://www.cnblogs.com/KeepZ/p/11343202.html

时间: 2024-07-31 22:46:25

素数筛法(Eratosthenes筛法)的相关文章

两种 eratosthenes 筛法的时间比较,第二种快很多会比较好用

#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int maxn = 10000005; int vis[maxn]; int n; //int eratosthenes() //{ //    memset(vis,0,sizeof(vis)); //    for(int i=2;i<=n;i++) /

【数学】【数论】素数的线性筛法

写在前面 记录了个人的学习过程,同时方便复习 素数的线性筛法 有时候需要筛出来一张素数表,即1~n范围内的所有素数 一个个枚举判断是否为素数显然太慢 于是经过仔细的研究之后,发现如果存在正整数k(k>2)不是素数,那么它的因子里面一定包含之前的素数 这样的话,开一个boolean数组标记一下不是素数的数,筛到它们的时候跳过就好 详见埃拉托斯特尼筛法 但是如果这样筛,显然会有重复的筛除啊 比如6筛去了42,7也筛去了42 这样的情况还有很多很多,十分影响效率,时间上并不是线性的 但如果按照一个数的

【素数】Eratosthenes筛选

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; int main() { /*素数筛选*/ /*Eratosthenes筛选*/ /*确定某一个数是素数之后,删除这个数的所有的倍数*/ int n; cin >> n; memset(vis, 0, sizeof(vis)); for(int i = 2; i <= sqrt(n); i

Eratosthenes,筛法求素数

//筛法求区间[0,n]的所有素数,v为素数表 //v[i]==0,i为素数 void f(int n) { int m=sqrt(n+0.5); memset(v,0,sizeof(v)); for (int i=2;i<=m;i++) if (!v[i]) for (int j=i*i;j<=n;j+=i) v[j]=1; }

埃氏素数筛法(Eratosthenes)

埃氏筛法: 对于每一个小于n的非负整数p,删去2p,3p,4p......,当处理完所有数后,还没有删除的就是素数. 想法:用a记录素数表,a[i]=1表示不是素数,a[i]=0表示是素数. #include <iostream> #include <algorithm> #include <cmath> using namespace std; int n,m,a[10000005],t; int main() { a[1]=1; cin>>n>&g

查找素数Eratosthenes筛法的mpi程序

思路: 只保留奇数 (1)由输入的整数n确定存储奇数(不包括1)的数组大小: n=(n%2==0)?(n/2-1):((n-1)/2);//n为存储奇数的数组大小,不包括基数1 (2)由数组大小n.进程号id和进程数p,确定每个进程负责的基数数组的第一个数.最后一个数和数组维度: low_value = 3 + 2*(id*(n)/p);//进程的第一个数 high_value = 3 + 2*((id+1)*(n)/p-1);//进程的最后一个数 size = (high_value - lo

数论快速入门(同余、扩展欧几里德、中国剩余定理、大素数测定和整数分解、素数三种筛法、欧拉函数以及各种模板)

数学渣渣愉快的玩了一把数论,来总结一下几种常用的算法入门,不过鶸也是刚刚入门, 所以也只是粗略的记录下原理,贴下模板,以及入门题目(感受下模板怎么用的) (PS:文中蓝色字体都可以点进去查看百度原文) 附赠数论入门训练专题:点我打开专题(题目顺序基本正常,用以配套数论入门) 一.同余定理 简单粗暴的说就是:若 a-b == m 那么 a%m == b%m 这个模运算性质一眼看出...直接上入门水题: Reduced ID Numbers 附AC代码(这个也没啥模板....知道就好) #inclu

一般筛法求素数+快速线性筛法求素数

素数总是一个比较常涉及到的内容,掌握求素数的方法是一项基本功. 基本原则就是题目如果只需要判断少量数字是否为素数,直接枚举因子2 ..N^(0.5) ,看看能否整除N. 如果需要判断的次数较多,则先用下面介绍的办法预处理. 一般的线性筛法 首先先介绍一般的线性筛法求素数 void make_prime() { memset(prime, 1, sizeof(prime)); prime[0]=false; prime[1]=false; int N=31700; for (int i=2; i<

【转载】一般筛法求素数+快速线性筛法求素数

素数总是一个比较常涉及到的内容,掌握求素数的方法是一项基本功. 基本原则就是题目如果只需要判断少量数字是否为素数,直接枚举因子2 ..N^(0.5) ,看看能否整除N. 如果需要判断的次数较多,则先用下面介绍的办法预处理. 一般的线性筛法 首先先介绍一般的线性筛法求素数 void make_prime() { memset(prime, 1, sizeof(prime)); prime[0]=false; prime[1]=false; int N=31700; for (int i=2; i<