如題,給定一個範圍 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;
}