YEAH DONG DONG
终于过了。
这样思考,首先,要把所有素数求出来是不可能的。注意到L,R的差仅一百万,那么就可以只求这个范围内的素数了。而筛选范围内的素数,就可以用上一篇的方法,使用若n为合数,则必有素因子在sqrt(n)中。
在筛选范围内的素数2了一次,直接判断每个数是否素数,TLE。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int LPR=50000;
const int Cprime=1000000;
const int inf=(1<<30);
bool isprime[LPR+10];
bool gsprime[Cprime+10];
__int64 prime[LPR],cp;
__int64 gprime[Cprime+10],gp;
void Isprime(){
memset(isprime,true,sizeof(isprime));
int e=(int)sqrt(LPR*1.0);
isprime[0]=isprime[1]=false;
for(int i=2;i<=e;i++){
if(isprime[i]){
for(int j=i*i;j<=LPR;j+=i)
isprime[j]=false;
}
}
}
void Doprime(){
cp=0;
for(int i=1;i<=LPR;i++)
if(isprime[i])
prime[cp++]=i;
}
/*
void Fprime(__int64 tp){
for(__int64 i=0;prime[i]*prime[i]<=tp;i++){
if(tp%prime[i]==0) return ;
}
gprime[gp++]=tp;
}
*/
void Fprime(__int64 L,__int64 R){
memset(gsprime,true,sizeof(gsprime));
__int64 tp=L;
if(L==1){
gsprime[0]=false;
L++;
}
for(__int64 i=0;i<cp;i++){
if(prime[i]>R) break;
__int64 s=L/prime[i];
if(s*prime[i]<L)
s++;
bool flag=false;
for(__int64 p=s*prime[i];p<=R;p+=prime[i]){
if(s==1&&!flag){
flag=true;
continue;
}
gsprime[p-tp]=false;
}
}
for(__int64 i=0;i<=R-tp;i++)
if(gsprime[i])
gprime[gp++]=i+tp;
}
int main(){
__int64 L,R; __int64 mind,maxd; __int64 mil,mir,mal,mar;
Isprime();
Doprime();
// cout<<prime[0]<<prime[1]<<prime[2]<<prime[3]<<endl;
while(scanf("%I64d%I64d",&L,&R)!=EOF){
// cout<<L<<' '<<R<<endl;
mind=inf; maxd=0;
gp=0;
/* for(__int64 i=L;i<=R;i++){
if(i==2){ gprime[gp++]=i; continue; }
if(i%2==0) continue;
Fprime(i);
}*/
Fprime(L,R);
if(gp==0||gp==1)
printf("There are no adjacent primes.\n");
else {
for(int i=0;i<gp-1;i++){
if(gprime[i+1]-gprime[i]<mind){
mind=gprime[i+1]-gprime[i];
mil=gprime[i]; mir=gprime[i+1];
}
if(gprime[i+1]-gprime[i]>maxd){
maxd=gprime[i+1]-gprime[i];
mal=gprime[i]; mar=gprime[i+1];
}
}
printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n",mil,mir,mal,mar);
}
}
return 0;
}