prime
題目描述
給定區間[L, R](L <= R <= 2147483647, R-L <= 1000000),請計算區間中
素數的個數。
輸入輸出
輸入
兩個數 L 和 R。
輸出
一行,區間中素數的個數。
樣例
樣例輸入
2 11
樣例輸出
5
說明
時空限制
時間限制 1s/testcase
空間限制 32MB
思路
R-L<=1000000
L <= R <= 2147483647
時間上用質數篩能過
求出2~45000的所有質數(sqrt(2147483647)大約是4300+)
然后將所有是這些質數的倍數的數刪掉,剩下的就是質數
空間上只有32mb,數組不能開太大,考慮到R-L<=1000000
完全可以只開到100005,之后對于大于100000的L和R,在存質數時
減去L即可。
代碼
/*
b[i]==1 i不是質數
b[i]==0 i是質數
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int i,j,k,l,t,n,m,ans;
int zhi[100005];
bool b[100005],z[1000005];
inline int read() {
int x=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar();
return x*w;
}
int main() {
freopen("prime.in","r",stdin);
freopen("prime.out","w",stdout);
for(i=2; i<=sqrt(100000); i++) {
if(!b[i]) {
for(j=2; j<=100000/i; j++) {
b[i*j]=1;
}
}
}
for(i=2; i<=100000; i++)if(!b[i])zhi[++zhi[0]]=i;
n=read();
m=read();
for(i=1; i<=zhi[0]; i++) {
for(j=max(n/zhi[i],1); j<=m/zhi[i]; j++) {
if(j==1)continue;
if(j*zhi[i]<n)continue;
z[zhi[i]*j-n]=1; //平移數組,控制空間大小
}
}
for(i=n-n; i<=m-n; i++) {
if(!z[i])++ans;
}
printf("%d\n",ans);
return 0;
}