这道题就是在区间中筛选素数,直接用筛选法会爆空间,每个数单独判断是不是素数,又会爆时间,所以就用了一个优化的筛选法,先算出数据范围每个合数可能的最小素因子,这样算每个区间是就不用再重复算这个素因子了,并且也不用每个数单独判断是不是素因子了,时间不超,空间也不超了,但是严格的时间复杂度的证明不会
参考链接:
http://blog.csdn.net/a601025382s/article/details/12111297
http://www.cnblogs.com/kuangbin/archive/2013/05/20/3089840.html
(感觉国庆放假比暑假更凄凉。继续龙族系列)
(每个人都会有些理由,可以让你豁出命去。你留着命……就是等待把它豁出去的那一 天。 ——江南 《龙族》,是要为自己喜欢的事豁出去,不是要去犯罪!!!)
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 1000010
#define M 65540
#define INF 0x3f3f3f3f
bool isprime[M];
int primenum[M];
bool issectionprime[N];
int sectionprime[N];
int cou;
int sectioncou;
void getprime(int a,int b){
memset(issectionprime,true,sizeof(issectionprime));
for(int i=0;(long long int)primenum[i]*primenum[i]<=(long long int)b&&i<cou;i++){//printf("%d %d\n",primenum[i],i);
int l=a/primenum[i];
if(a%primenum[i]){
l++;
}
if(l==1){//注意:这里如果l=1的话,那么乘出来就是素数,而不是合数
l++;
}
for(long long int j=l;j*primenum[i]<=(long long int)b;j++){
issectionprime[j*primenum[i]-a]=false;
}
}
if(a==1){
issectionprime[0]=false;
}
sectioncou=0;
for(int i=0;i<=b-a;i++){
if(issectionprime[i]){
sectionprime[sectioncou++]=a+i;
}
}
return;
}
int main(){
cou=0;
memset(isprime,true,sizeof(isprime));
//isprime[1]=false;
for(int i=2;i*i<=M-1;i++){//把M写成了N,所以越界,造成primenum[0]=0
if(isprime[i]){
//primenum[cou++]=i;这句不能写里面,因为i最多遍历到i*i<=M-1,因此会造成大于sqrt(M-1)的素数没被加进primenum这个数组里
/*if(i==3917){
printf("hahaha\n");
}*/
//printf("%d %d\n",cou-1,primenum[cou-1]);
for(int j=i+i;j<M;j=j+i){
/*if(j==3917){
printf("hahaha\n");
}*/
isprime[j]=false;
}
}
}
//printf("%d\n",primenum[0]);
for(int i=2;i<M;i++){
if(isprime[i]){
primenum[cou++]=i;
}
}
int a,b;
while(scanf("%d%d",&a,&b)!=EOF){
getprime(a,b);
int min=INF;
int minnum;
int max=-1;
int maxnum;
for(int i=0;i<sectioncou-1;i++){
//printf("%d\n",sectionprime[i]);
/*if(sectionprime[i]==2146841093||sectionprime[i]==2146841273){
printf("%d %d\n",sectionprime[i],sectionprime[i+1]);
}*/
int jg=sectionprime[i+1]-sectionprime[i];
if(jg<min){
min=jg;
minnum=i;
}
if(jg>max){
max=jg;
maxnum=i;
}
}
//printf("%d\n",sectionprime[sectioncou-1]);
if(max==-1){
printf("There are no adjacent primes.\n");
}
else{
printf("%d,%d are closest, %d,%d are most distant.\n",sectionprime[minnum],sectionprime[minnum+1],sectionprime[maxnum],sectionprime[maxnum+1]);
}
}
return 0;
}