1. 程式人生 > >P1835 素數密度_NOI導刊2011提高(04)

P1835 素數密度_NOI導刊2011提高(04)

bsp bre 輸入輸出 long long 輸入輸出格式 void span rim init

題目描述

給定區間[L,R](L≤R≤2147483647,R-L≤1000000),請計算區間中素數的個數。

輸入輸出格式

輸入格式:

兩個數L和R。

輸出格式:

一行,區間中素數的個數。

輸入輸出樣例

輸入樣例#1:
2 11
輸出樣例#1:
5

Solution:

  本題比較模板()。

  因為$int_{max}$範圍內的合數只需用$\sqrt {int_{max}}\leq 50000$內的質數就能篩出。

  於是,預處理出$50000$內的質數,然後埃式篩掉$[l,r]$範圍內的合數就好了,隨便瞎搞一下就好了。

  最後統計一下質數個數並輸出。

代碼:

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define ll long long
 4 #define For(i,a,b) for(ll (i)=(a);(i)<=(b);(i)++)
 5 #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
 6 using namespace std;
 7 const int N=50005,M=1000005;
 8 int l,r,prime[N+5],cnt;
9 bool isp[N+5],isprime[M+5]; 10 11 il void init(){ 12 For(i,2,N){ 13 if(!isp[i]) prime[++cnt]=i; 14 for(int j=1;j<=cnt&&prime[j]*i<=N;j++){ 15 isp[prime[j]*i]=1; 16 if(i%prime[j]==0)break; 17 } 18 } 19 } 20 21 il void
solve(){ 22 ll p,q; 23 For(i,1,cnt){ 24 if(prime[i]>r)break; 25 p=ceil(l*1.0/prime[i]),q=ceil(r*1.0/prime[i]); 26 if(p==1)p=2; 27 for(int j=p;j<=q&&prime[i]*j<=r;j++) 28 isprime[prime[i]*j-l+1]=1; 29 } 30 int tot=0; 31 For(i,1,r-l+1) if(!isprime[i]) tot++; 32 cout<<tot; 33 } 34 35 int main(){ 36 init(); 37 cin>>l>>r; 38 solve(); 39 return 0; 40 }

P1835 素數密度_NOI導刊2011提高(04)