Prime Distance(素数筛)

原题见洛谷。

首先一次预处理出根号R内的所有质数。虽然L,R很大但是它们相差不大,对于每个筛出来的质数,把[L,R]内所有能被它整除的数标记,然后剩下的数从L到R扫一遍就可以统计答案了。注意标记时的细节。

#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAXN=46500;
int vis[1000005],tot=0;
LL prime[MAXN];

void pre()
{
	for(LL i=2;i<=46500;i++)
	{
		if(!vis[i]) prime[++tot]=i;
		for(LL j=1;j<=tot&&prime[j]*i<=46500;j++)
		{
			vis[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}

int main()
{
	pre();
	LL L,R;
	while(scanf("%lld%lld",&L,&R)==2)
	{
		memset(vis,0,sizeof(vis));
		for(LL i=1;i<=tot&&prime[i]<=R;i++)
		{
			for(LL j=L/prime[i];j<=R/prime[i];j++)
				if(j>1&&j*prime[i]>=L) vis[j*prime[i]-L]=1;
		}
			
		if(L==1) vis[0]=1;
		
		LL dis1=R-L+1,dis2=0,lastp=-1,x1,y1,x2,y2;
		for(int i=0;i<=R-L;i++)
		{
			if(!vis[i])
			{
				if(lastp>=0)
				{
					if(i-lastp<dis1)
					{
						dis1=i-lastp;
						x1=lastp; y1=i;
					}
					
					if(i-lastp>dis2)
					{
						dis2=i-lastp;
						x2=lastp; y2=i;
					}
				}
				lastp=i;
			}
		}
		if(!dis2) puts("There are no adjacent primes.");
		else cout<<x1+L<<','<<y1+L<<" are closest, "<<x2+L<<','<<y2+L<<" are most distant.\n";
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/WWWengine/article/details/82315327
今日推荐