~素數數目~~~~區間篩法

題目描述(這裏可以點哦)
給定區間[L,R],計算區間素數個數。
輸入
輸入兩個整數L,R(1<=L<=R<=10^12,R-L<=1000000)
輸出
輸出一行表示區間素數的個數
樣例輸入 Copy
2 11
樣例輸出 Copy
5

素數個數問題,一般就是用埃氏篩法(複雜度O(nloglogn)),這題自然也不例外,具體思路如下:
第一步,用埃氏篩法得到1 ~ R1/2之間的全部素數;
第二步,用第一步得到的素數表把區間 [ L,R ]中的所有合數篩去;
第三部,統計剩下的素數個數;

事實上第一步和第二步是放在一起進行的,代碼如下:

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e6+1;
bool f[N],t[N];//需要篩兩個區間
LL L,R;
LL S_sieve(LL l,LL r){//區間篩法 
	if(l==1)t[1]=true;
	for(LL i=2;i*i<=r;++i){
		//篩選2~sqrt(r)之間的素數 
		if(f[i])continue;
		for(LL j=2*i;j*j<=r;j+=i){   //j不能等i*i
			f[j]=true;
		}
		//用篩選出的質數篩去區間l~r的合數 
		LL s=max((l-1)/i+1,i);       //保守i*i 
		for(LL j=s*i;j<=r;j+=i){
			t[j-l+1]=true;
		}
	}	
	LL sum=0; //統計區間內素數個數
	for(LL i=1;i<=r-l+1;++i){
		if(t[i])continue;
		++sum;
	}
	return sum;
}
int main(){
	cin>>L>>R;
	cout<<S_sieve(L,R)<<endl;
	return 0;
}

溫馨提示:如果你的代碼提交之後,出現運行錯誤,請留意第四處註釋。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章