题意:给定L,R,其中L,R <= 2^32,但是R-L <= 1e6。求[L,R]中,相邻素数中最近和最远的两个素数。
好坑啊,思路是很明显:
R-L比较小,所以我们用小区间去筛大区间。首先R最大是2^32
则区间内的数最大用2^16就可以筛出来。
所以我们先预处理2^16内的素数。然后每次输入L,R,我就去用每一个素数去筛给定的L,R
但是L,R很大,用map会超时,所以我们把L,R离散到1,R-L+1。
同时为了防止多组数据每组数据的R-L+1都很小,我们用for去初始化。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<ctime>
#define up(i,x,y) for(int i = x;i <= y;i ++)
#define down(i,x,y) for(int i = x;i >= y;i --)
#define mem(a,b) memset((a),(b),sizeof(a))
#define mod(x) ((x)%MOD)
#define lson p<<1
#define rson p<<1|1
using namespace std;
typedef long long ll;
const int SIZE = 2000010;
const int INF = 2147483640;
const double eps = 1e-8;
inline void RD(int &x)
{
x = 0; char c; c = getchar();
bool flag = 0;
if(c == '-') flag = 1;
while(c < '0' || c > '9') {if(c == '-') {flag = 1;} c = getchar();}
while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - '0',c = getchar();
}
int up = 65536;
bool vis[SIZE],vis2[SIZE];
ll a,b;
ll l,r;
int main(int argc, char const *argv[])
{
for(int i = 2;i <= up;i ++)
{
if(!vis[i])
{
for(int j = i+i;j <= up;j += i) vis[j] = 1;
}
}
while(~scanf("%lld%lld",&l,&r))
{
up = ((int)((double)(sqrt((double)r))))+1;
for(ll i = 2;i <= (ll)up;i ++)
{
if(!vis[(int)i])
{
if(l <= i) a = i + i;
else if(l % i == 0) a = l;
else a = (l / i + 1) * i;
if(a == i) a += i;
for(ll j = a;j <= r;j += i)
{
// printf("wsm? %d\n",(int)(j-l+1ll));
vis2[int(j-l+1ll)] = 1;
}
}
}
if(l == 1ll) vis2[1] = 1;
int lst = -1;
ll minn = INF,maxx = -1;
int min_1 = INF,min_2,max_1,max_2;
for(int i = 1;i <= (int)(r-l+1);i ++)
{
if(!vis2[i])
{
// printf("i,lst: %d %d\n",i,lst);
if(lst != -1)
{
if(minn > i - lst)
{
minn = i - lst;
min_1 = lst;
min_2 = i;
}
if(maxx < i - lst)
{
maxx = i - lst;
max_1 = lst;
max_2 = i;
}
}
lst = i;
}
}
if(maxx != -1 && minn != INF) printf("%d,%d are closest, %d,%d are most distant.\n",min_1-1+(int)l,min_2-1+(int)l,max_1-1+(int)l,max_2-1+(int)l);
else printf("There are no adjacent primes.\n");
ll qaq = r-l+1ll;
int qwq = (int)qaq;
for(ll i = 1;i <= qaq;i ++) vis2[i] = 0;
}
return 0;
}
/*
2 17
2 17
2 17
14 17
2 3
1147400000 1147499999
*/