给出一个区间 让你求区间内数的素数数量。区间[1,2^31)
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
const int maxn=50000;
int prime[maxn],primelen;
bool vis[maxn*2+5];
void makeprime()
{
primelen=0;
for(int i=2;i<maxn;i++)
{
if(!vis[i]) prime[primelen++]=i;
for(int j=0;j<primelen&&i*prime[j]<maxn;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]!=0) break;
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
makeprime();
int t;
scanf("%d",&t);
for(int k=1;k<=t;k++)
{
int a,b;
scanf("%d%d",&a,&b);
memset(vis,0,sizeof(vis));
if(a==1) a=2;
int ans=0,n=b-a,en=sqrt(b);
for(int i=0;i<primelen&&prime[i]<=en;i++)
{
int j=0;
///找到第一个 (j+a)%prime[i]==0
if(a%prime[i]!=0) j=prime[i]-a%prime[i];
if(a<=prime[i])///为(j+a)当前质数
j+=prime[i];
for(;j<=n;j+=prime[i])
vis[j]=1;
}
for(int j=0;j<=n;j++)
if(!vis[j]) ans++;
printf("Case %d: %d\n",k,ans);
}
return 0;
}
使用小素数表来筛大素数表。
为什么使用sqrt(n)内的素数就可以将n内的所有合数筛完
///假设我们有有个最大合数没有被筛掉 那么这个合数就可以表示为某个素数和某个数的乘积。 ///某个数:假设数合数那么最大的合数就不存在。该数只能是素数。 ///假设比上一个素数小,那么该数也不存在,所以只能是素数^2。
///大于该素数就超出范围了