埃氏篩是一種很基礎簡單實用的篩素數的算法
具體的思想便是如下:
從2開始,(因爲所有數都是1的倍數,故不可),我們給所有2的倍數都打上標記(是合數)
之後最小的數就是3了,我們往後去,給所有3的倍數都打上標記
依次類推
這裏給出一道埃氏篩的模板搜索題
LUOGU P1865 A % B Problem
題目背景
題目名稱是吸引你點進來的
實際上該題還是很水的
題目描述
區間質數個數
輸入格式
一行兩個整數 詢問次數n,範圍m
接下來n行,每行兩個整數 l,r 表示區間
輸出格式
對於每次詢問輸出個數 t,如l或r∉[1,m]輸出 Crossing the line
輸入輸出樣例
輸入 #1 複製
2 5
1 3
2 6
輸出 #1 複製
2
Crossing the line
說明/提示
【數據範圍和約定】
對於20%的數據 1 <= n <= 10 1 <= m <= 10
對於100%的數據 1 <= n <= 1000 1 <= m <= 1000000 -10^9 <= l <= r<=10^9 1 <= t <= 1000000
分析
這裏可以看出與通常的不同,這裏是需要我們來計數的
對於每一個前綴和的量,在這個數是合數時也就是前一個的量,在是質數時就需要加上了
#include <bits/stdc++.h>
using namespace std;
long f[1000009];
bool judge[1000009];
long n,m;
void work() { //埃氏篩+前綴和(計數)
for (int i = 2; i <= m; i++) {
f[i] = f[i-1]; //前綴和(一般的情況)
if (!judge[i]) { //噹噹前的數是質數時(特例),要加上
f[i]++;
for (int j = i*2; j <= m; j+=i) judge[j] = true;
}
}
}
int main() {
cin>>n>>m;
work();
for (int i = 1; i <= n; i++) {
long l,r;
cin>>l>>r;
if (l < 1 || r > m) { //不在範圍內(∉)
cout<<"Crossing the line"<<endl;
continue;
}
long ans = f[r] - f[l-1]; //計算值
cout<<ans<<endl;
}
return 0;
}