题意:给出了T组询问,每次询问给出L,R,求出每次[L,R]间相差最大以及最小的相邻素数。
题解:由于L,R都很大所以没法直接用欧拉筛筛到。但是我们注意到L,R的差为1e6,可以用数组存下。并且我们可以知道任意一个合数n都拥有一个不大于sqrt(n)的素因数,所以我们可以预处理出1~2^16的所有质数,每次用这些质数筛出来l,r区间的质数,并且存在数组[0,u-l]中即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#define lim 500100
#define inf 0x3f3f3f3f
using namespace std;
int prime[1001000],f[1001000],l,r,ToT;
void getprime(){
for (int i=2;i<lim;i++){
if (!f[i]) prime[++ToT]=i;
for (int j=1;j<=ToT&&prime[j]*i<lim;j++){
f[i*prime[j]]=1;
if (i%prime[j]==0) break;
}
}
}
int main(){
getprime();
for (;~scanf("%d%d",&l,&r);){
if (l==1) l=2;
memset(f,0,sizeof(f));
for (int i=1;i<=ToT;i++){
int a=(l-1)/prime[i]+1,b=r/prime[i];
for (int j=a;j<=b;j++)
if (j>1) f[prime[i]*j-l]=1;
}
int last=-1,maxx=-inf,minn=inf,x1,y1,x2,y2;
for (int i=0;i<=r-l;i++){
if (!f[i]){
if (last==-1) {last=i;continue;}
if (i-last>maxx) maxx=i-last,x1=last+l,y1=i+l;
if (i-last<minn) minn=i-last,x2=last+l,y2=i+l;
last=i;
}
}
if (maxx==-inf&&minn==inf) printf("There are no adjacent primes.\n");
else printf("%d,%d are closest, %d,%d are most distant.\n",x2,y2,x1,y1);
}
return 0;
}