埃氏篩(P1865 A % B Problem)

埃氏篩是一種很基礎簡單實用的篩素數的算法
具體的思想便是如下:
從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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章