POJ 2689 Primer Distance 埃式筛法

题意:给定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
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值