洛谷題集——線性篩素數(一般篩選與線性篩選)

如題,給定一個範圍 n,有 q 個詢問,每次輸出第 k 小的素數。

輸入格式
第一行包含兩個正整數 n,q,分別表示查詢的範圍和查詢的個數。
接下來 q 行每行一個正整數 k,表示查詢第 k 小的素數。
輸出格式
輸出 q 行,每行一個正整數表示答案。

輸入輸出樣例
輸入 #1 複製
100 5
1
2
3
4
5
輸出 #1 複製
2
3
5
7
11
說明/提示
【數據範圍】
對於100% 的數據,n = 108,1≤q≤106,保證查詢的素數不大於 n。


【普通篩——埃拉託斯特尼(Eratosthenes)篩法】
時間複雜度O(n * loglogn)

#include<cstdio>
#define ll long long
using namespace std;
ll n, num=1;
ll ss[100000010];
int Q[1000010], q;
bool judge[100000010]={false};
void init(void){
	judge[1]=true;
	
	for(ll i=2; i<=n; i++){
		if(judge[i]==false){
			ss[num++]=i;
			for(int j=2; j*i<=n; j++){
				judge[i*j]=true;
			}
		}
	}
}

int main(){
	scanf("%lld%d", &n, &q);
	init();
	for(int i=0; i<q; i++){
		scanf("%d", &Q[i]);
	}
	for(int i=0; i<q; i++){
		printf("%lld", ss[Q[i]]);
		if(i<q-1){
			printf("\n");
		}
	}
	
	return 0;
}

測試結果很感人,一個都沒過……


【線性篩——歐拉Euler篩】
時間複雜度爲O(n)
歐拉篩解析

#include<stdio.h>
int n, num=1;
int ss[100000010];
int Q[1000010], q;
bool judge[100000010]={false};

void init(void){
	judge[1]=true;
	
	for(int i=2; i<=n; i++){ 	
		if(judge[i]==false){
			ss[num++]=i;
		}
		for(int j=1; ss[j]*i<=n&&j<num; j++){
			judge[i*ss[j]]=true;	
			//兩個或兩個以上素數相乘能夠得到全部非素數 
			if(i%ss[j]==0){			
			//若i爲素數的倍數則i不是素數 
				break;				
			}
		}
	}
}

int main(){
	scanf("%d%d", &n, &q);
	init();
	for(int i=0; i<q; i++){
		scanf("%d", &Q[i]);
	}
	for(int i=0; i<q; i++){
		printf("%d", ss[Q[i]]);
		if(i<q-1){
			printf("\n");
		}
	}
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章