1. 程式人生 > 實用技巧 >【模板】線性篩素數

【模板】線性篩素數

例題洛谷P3383
原理大概是在如2的倍數不是素數,3的倍數不是素數這樣來排除素數時,會出現重複排除比如6。
線性篩素數避免了重複排除 實現了O(n)時間複雜度
貼一個洛谷題解程式碼

#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
	int n,q,check[100000001]={0};
	int prime[1000001],cnt=0;
	//根據n<=10^8,q<=10^6開對應的陣列大小,防止MLE
	//初始將check陣列全部標記為0,標0的是素數,標1的不是素數
	scanf("%d%d",&n,&q);
	check[1]=1;//1不是素數
	for(int i=2;i<=n;i++)
	{
		if(!check[i])prime[cnt++]=i;//若當前數i沒有被之前的所有數篩掉,表明i是素數,將i新增進素數表prime
		for(int j=0;j<cnt&&i*prime[j]<100000001;j++)//注意i*prime[j]不要超過n的上限(10^8)
		{
			check[i*prime[j]]=1;//將當前素數prime[j]的i倍標記為合數
			if(i%prime[j]==0)break;//關鍵步驟:保證每個合數只被篩一次
		}
	}
	for(int i=1;i<=q;i++)
	{
		scanf("%d",&n);
		printf("%d\n",prime[n-1]);//由於素數表從0開始存,所以輸出時下標應減1
	}
	return 0;
}