题目大意:
给出多个询问,每个询问给出区间[l,r],问其中相邻素数差最小的一对数是多少,差最大的一对数是多少。
1 <= L < R <=2,147,483,647
分析:
筛除[1,根号2^31]之间的素数
然后对于每次给出的询问[l,r]
我们用素数表处理出其中的素数,注意判断一下l=1的情况,
而且注意不知道为什么,直接枚举l~r会炸,虽然只有1e6的长度…
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define N 1000005
#define M 17
using namespace std;
int prime[1<<M],v[1<<M],a[N],cnt = 0,l,r;
void work(){
for (int i = 2; i <= 1<<M; i++){
if (!v[i]){
prime[++cnt] = i;
v[i] = i;
}
for (int j = 1; j <= cnt; j++){
if (prime[j] > v[i] || prime[j]*i > 1<<M) break;
v[prime[j]*i] = prime[j];
}
}
}
int main(){
work();
while (cin >> l >> r){
memset(a, 0, sizeof(a));
if (l == 1) l = 2;
for (int i = 1; i <= cnt; i++){
if (prime[i] > r) break;
int x = prime[i];
int a1 = (l-1)/x+1, b1 = r/x;
if (a1 == 1) a1 = 2;
for (int j = a1; j <= b1; j++) a[j*x-l+1] = 1;
}
int x = 0, y = 0;
int cha1 = N, min1 = 0, min2 = 0;
int cha2 = 0, max1 = 0, max2 = 0;
for (int i = 1; i <= r-l+1; i++)
if (!a[i]){
if (!x) x = i+l-1;
else {
y = x, x = i+l-1;
if (x-y < cha1) cha1 = x-y, min1 = y, min2 = x;
if (x-y > cha2) cha2 = x-y, max1 = y, max2 = x;
}
}
if (!min1) cout<<"There are no adjacent primes."<<endl;
else cout<<min1<<","<<min2<<" are closest, "<<max1<<","<<max2<<" are most distant."<<endl;
}
return 0;
}