素数筛(1) 埃氏筛法

其原理就是先将2-n之内的所有数存在一个数组里,初始化所有数全为素数,然后从2开始寻找,只要标记是素数便将他的所有倍数的标记都改为合数,依次类推。时间复杂度为O(nloglogn)。

代码实现

1 void prime_table()
2 {
3     for(int i=2;(LL)i<=n;i++) prime[i]=1;
4     for(int i=2;(LL)i*i<=n;i++)
5             if(prime[i]) for(LL j=i*i;j<=n;j+=i) prime[j]=0;
6 }
素数筛

区间素数筛

当要求的范围过大时,上述方法会爆内存,所以我们可以先做好【2,√b)和【a,b)的表,在筛【2,√b)的同时将其倍数在【a,b)中划去。

40027120区间内素数的个数
难度级别:B; 运行时间限制:1000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述

给定两个正整数 a 和 b,请你统计区间 [a,b) 内有多少个素数。

输入
共一行包含两个正整数 a 和 b,用一个空格分隔开。
输出
一个数,表示所给区间内的素数的个数。
输入示例
22 37
输出示例
其他说明
数据范围:1≤ a < b ≤ 10^12 , b-a ≤ 10^7 。
样例说明:有23、 29 和 31 共 3 个素数。
 1 #include<iostream>
 2 using namespace std;
 3 #define LL long long
 4 LL read()
 5 {
 6     LL x=0,f=1;
 7     char c=getchar();
 8     while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
 9     while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
10     return x*f;
11 }
12 #define maxn 1000010
13 bool prime[maxn], is[maxn];
14 LL a, b;
15 void prime_table()
16 {
17     for(int i = 2; (LL)i * i < b; i++) prime[i] = 1;
18     for(int i = 0; i < b - a; i++) is[i] = 1;
19     for(int i = 2; (LL)i * i < b; i++) if(prime[i]) {
20         for(LL j = 2 * i; j * j < b; j += i) prime[j] = 0;
21         for(LL j = max(2LL, (a + i - 1) / i) * i; j <= b; j += i) if(j >= a) is[j-a] = 0;
22     }
23     return ;
24 }
25 
26 int main()
27 {
28     a = read(); b = read();
29     prime_table();
30     int cnt = 0;
31     for(int i = 0; i < b - a; i++) if(is[i]) cnt++;
32     if(a == 1) cnt--;
33     printf("%d
", cnt);
34     
35     return 0;
36 }
View Code
O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
原文地址:https://www.cnblogs.com/wls001/p/5156997.html