埃氏筛选 - 素数的个数

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;

const int maxn = 1000000 + 200;
int prime[maxn];          //第i个素数
bool is_prime[maxn + 1];  //is_prime[i]位true, 表示i是素数 

void solve();
int sieve(int n);

//返回n以内素数的个数
int sieve(int n)
{
    int p = 0;
    for (int i = 0; i <= n; i++) is_prime[i] = true;
    is_prime[0] = is_prime[1] = true;
    for (int i = 2; i <= n; i++) {
        if (is_prime[i]) {          //是素数
            prime[p++] = i;
//            cout << i << " ";     //输出素数(每次剩余的最小数字是i,i就是素数)
            for (int j = 2*i; j <= n; j += i) is_prime[j] = false;  //将i的倍数全部划去
        }
    }
    return p;
}

void solve()
{
    int n;
    scanf("%d", &n);
    cout << sieve(n) << endl;
}

int main()
{
    solve();
    return 0;
} 

埃氏筛法的复杂度是O(nloglogn)

时间: 2024-09-30 23:52:24

埃氏筛选 - 素数的个数的相关文章

埃氏筛法(素数筛)

埃式筛法:给定一个正整数n(n<=10^6),问n以内有多少个素数? 做法:做法其实很简单,首先将2到n范围内的整数写下来,其中2是最小的素数.将表中所有的2的倍数划去,表中剩下的最小的数字就是3,他不能被更小的数整除,所以3是素数.再将表中所有的3的倍数划去……以此类推,如果表中剩余的最小的数是m,那么m就是素数.然后将表中所有m的倍数划去,像这样反复操作,就能依次枚举n以内的素数,这样的时间复杂度是O(nloglogn). 题解:如果要是按照一个一个判断是否是素数然后把ans+1,时间复杂度

埃氏筛素数

#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; int jdg[10000001],n,m; int main() { cin>>n>>m; jdg[1]=1; for(int i=2;i<=n;i

埃氏筛法(快速筛选n以内素数的个数)

给你一个数n,请问n以内有多少个素数?(n <= 10e7) 一般来说,要是对一个整数进行素数判断,首先想到的是写个函数判断是否为素数,然后调用这个函数,时间复杂度为O(n^(½)),但是要求n以内的素数就略显吃力了. 要是求n以内的素数个数的话,可以用埃式筛选.预处理一下. 先看下面的代码: 1 /* 2 |埃式筛法| 3 |快速筛选素数| |15-7-26| 4 */ 5 #include <iostream> 6 #include <cstdio> 7 using na

区间内素数的个数(也要用到埃氏算法)

题目大意:给定正整数a和b,请问区间[a,b)内有多少个素数 限制条件:a<b<=10^12    b-a<=10^6 样例: 22 37 3 22801763489 22801787297 1000 思路:由于b以内的合数的最小质因数一定不超过根号b,所以如果有根号b以内的素数表的话,就可以用埃氏算法运用在[a,b)上了.  也就是说,先分别做好[2,根号b)的表和[a,b)的表, 然后从[2,根号b)的表中筛得素数的同时,也将其倍数从[a,b)的表中划去,最后剩下的就是[a,b)以内

素数的快速筛选(埃氏筛法)

要枚举n以内的素数,可以用埃氏筛法.这是一个与辗转相除法一样古老的算法. 首先,将2到n范围内的所有整数写下来.其中最小的数字2是素数.将表中所有2的倍数都划去.表中剩余的最小数字是3,它不能被更小的数整除,所以是素数.再将表中所有3的倍数全都划去.依次类推,如果表中剩余的最小数字是m时,m就是素数.然后将表中所有m的倍数全部划去.像这样反复操作,就能依次枚举n以内的素数. int prime[maxn];//第i个素数 bool is_prime[maxn];//is_prime[i]为tru

分拆素数和 埃氏筛法

分拆素数和 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 2098 Description 把一个偶数拆成两个不同素数的和,有几种拆法呢? Input 输入包含一些正的偶数,其值不会超过10000,个数不会超过500,若遇0,则结束. Output 对应每个偶数,输出其拆成不同素数的个数,每个结果占一行. Sample Input 30

埃氏筛法之素数

原理: 首先将2~n个数记录下来,2作为最小素数,所以2的倍数不是素数,从记录中划去,扫一遍之后,将3作为最小素数,3的倍数划去,如此下去,求出所有素数.如表格所示: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 3 - 5 - 7 - 9 - 11 - 13 - 15 - 17 - 19 - 2 3 - 5 - 7 - - - 11 - 13 - - - 17 - 19 - 代码: 判断是否是素数: bool is_prime(int n

素数表的获取(埃氏筛和欧拉筛)

Eratosthenes筛法(埃氏筛) 时间复杂度:O(nlognlogn) 思路 代码 const int maxn=1e6+10; //表长 int prime[maxn],cnt=0; //prime数组存放所以素数,cnt为素数个数 bool st[maxn]; //false为素数 void get_prime(int n){ for(int i=2;i<=n;i++){ if(!st[i]){ prime[cnt++]=i; //把素数i存到prime数组中 for(int j=i+

【算法杂谈】埃氏素数筛

[今天我们来讲讲筛子] [埃氏筛的基本思想] 简单来说就是把不大于(n为数据范围)以内的素数的倍数全都去掉,那么剩下的就是2~n之间的素数了. [举个例子] 我们假设现在n是25. 第一步:先把2作为筛子,那么所有2的倍数都被筛掉了. 则当前序列为:2 3 5 7 9 11 13 15 17 19 21 23 25 第二步:剩下的序列中第一个素数是3,将序列中3的倍数划掉. 则当前序列为:2 3 5 7 11 13 17 19 23 25 25仍然大于3的平方,所以我们还要继续筛 现在序列中第一