题目:求区间[L,R]中最近的2个相邻素数和最远的2个相邻素数
1<=L< R<=2,147,483,647
R-L<=1e6
思路:直接用素数筛
代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<ctime>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<list>
#include<numeric>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define INF 0x3f3f3f3f3f3f3f3f
#define mm(a,b) memset(a,b,sizeof(a))
#define PP puts("*********************");
template<class T> T f_abs(T a){ return a > 0 ? a : -a; }
template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
// 0x3f3f3f3f3f3f3f3f
const int maxn=1e6+50;
bool isprime[maxn];
int prime[maxn],tol;
void make_prime(int n){
for(int i=0;i<=n;i++)
isprime[i]=true;
isprime[0]=isprime[1]=false;
tol=0;
for(int i=2;i<=n;i++){
if(isprime[i])
prime[tol++]=i;
for(int j=0;j<tol;j++){
if(i*prime[j]<=n)
isprime[i*prime[j]]=false;
else
break;
if(i%prime[j]==0)
break;
}
}
}
LL arr[maxn];
bool vis[maxn];
int main(){
LL L,R;
LL x1,y1,x2,y2;
make_prime(100050);
while(~scanf("%lld%lld",&L,&R)){
if(L==1) L=2;
mm(vis,false);
for(int i=0;i<tol&&(LL)prime[i]*prime[i]<=R;i++){
LL pos=L/prime[i]*prime[i];
if(pos<L) pos+=prime[i];
pos=max(pos,(LL)2*prime[i]);
for(LL j=pos;j<=R;j+=prime[i])
vis[j-L]=true;
}
int cnt=0;
for(LL i=L;i<=R;i++)
if(vis[i-L]==false)
arr[cnt++]=i;
if(cnt<2){
printf("There are no adjacent primes.\n");
}
else{
for(int i=0;i<=cnt-2;i++){
if(i==0){
x1=arr[i];y1=arr[i+1];
x2=arr[i];y2=arr[i+1];
}
if(y1-x1>arr[i+1]-arr[i]){
x1=arr[i];y1=arr[i+1];
}
if(y2-x2<arr[i+1]-arr[i]){
x2=arr[i];y2=arr[i+1];
}
}
printf("%lld,%lld are closest, %lld,%lld are most distant.\n",x1,y1,x2,y2);
}
}
return 0;
}