[POJ 2689] Prime Distance

Description

给定两个整数 \(L,R\;(1\leq L\leq R\leq 2^{31},R-L\leq 10^6)\) ,求闭区间 \([L,R]\) 中相邻两个数最大的差是多少,输出这些质数。

Solution

任何一个合数 \(N\) 必定包含一个不超过 \(\sqrt N\) 的质因子。

所以,我们只需要用筛法求出 \(2-\sqrt N\) 之间的所有质数。对于每个质数 \(p\) ,把 \([L,R]\) 中能被 \(p\) 整除的数标记。

最终所有未被标记的数就是 \([L,R]\) 中的质数,对相邻的质数两两比较,找出差最大的即可。

还有一个要注意的是这题 \(L,R\) 范围太大,数组开不小,所以对于每个询问,都要加一个偏移量来进行标记和判断。

Code

#include<cmath>
#include<cstdio>
#include<cstring>
#define N 52005

int l,r;
int sum[1000005];
bool is_prime[N+10];
int prime[N],primecnt;

void init(int n){
	is_prime[1]=1;
	for(int i=2;i<=N;i++){
		if(!is_prime[i])
			prime[++primecnt]=i;
		for(int j=1;j<=primecnt;j++){
			if(i*prime[j]>N) break;
			is_prime[i*prime[j]]=1;
			if(i%prime[j]) break;
		}
	}
}

signed main(){
	init(N);
	while(~(scanf("%d%d",&l,&r))){
		memset(sum,0,sizeof sum);
		if(l==1) l++;
		for(int i=1;i<=primecnt;i++){
			for(int j=l/prime[i];j<=r/prime[i];j++){
				if(prime[i]*j<l) continue;
				if(j==1) continue;
				sum[prime[i]*j-l]=1;
			}
		}
		int tot=0,last=0;
		int max1,max2,min1,min2;
		int maxn=0xcfcfcfcf,minn=0x3f3f3f3f;
		for(int i=0;i<=r-l;i++){
			//printf("i=%d,sum=%d\n",i,sum[i]);
			if(sum[i]) continue;
			tot++;
			if(tot>1){
				if(maxn<i-last){
					maxn=i-last;
					max1=last,max2=i;
				}
				if(minn>i-last){
					minn=i-last;
					min1=last,min2=i;
				}
			}
			last=i;
		}
		if(tot==1)
			printf("There are no adjacent primes.\n");
		else
			printf("%d,%d are closest, %d,%d are most distant.\n",min1+l,min2+l,max1+l,max2+l);
	}
	return 0;
}
posted @ 2018-05-11 21:18  YoungNeal  阅读(185)  评论(0编辑  收藏  举报