ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

POJ prime distance

2021-07-27 12:34:43  阅读:216  来源: 互联网

标签:prime distance minl ll 素数 POJ INF prime2 lld


https://oj.shiyancang.cn/Problem/781.html

素数距离,数据范围21亿,如果用素数筛存,并且进行做的话,按照x/lnx计算会是一个非常恐怖的复杂度。确定要做什么,首先一定要筛选素数,然后一定要进行素数的比较。问题就在筛选素数这里,可以看到区间范围很小,可以从这里入手,怎么储存,不可能按照那个储存,可以进行离散化,或者偏移,等等注意1的存在,无法被素数筛选掉,注意越界问题,那么就是区间素数筛选,埃氏筛的使用。因为算数基本定理,必然有小于sqrt的素数因子,这是可以接受的。那么sqrt再x、lnx就会很小了,每次一个1e4的复杂度直接解决了,求出a,b.储存上一状态的量,逐一比较即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+520;
const ll INF=0x3f3f3f3f;
ll prime1[N],cnt,prime2[N*10],l,r;
bool st[N*10];
void get_prime(ll n)
{
	for(int i=2;i<=n;i++)
	{
		if(!st[i]) prime1[cnt++]=i;
		for(int j=0;prime1[j]<=n/i;j++)
		{
			st[prime1[j]*i]=1;
			if(i%prime1[j]==0) break;
		}
	}
}
void get_prime2()
{
	ll a,b;
	memset(st,0,sizeof(st));
	for(ll i=0;i<cnt;i++)//要么刚好,要么卡进区间, 但是如果是1的话,那么意味着没有任何一个可以通过素数筛选掉他 
	{
		a=(l-1)/prime1[i]+1,b=r/prime1[i];//向上进位,  //prime卡进区间范围内,(l-1)卡进里面去,但是L是从零开始的了 
		for(ll j=a;j<=b;++j) 
		{
			if(j>1) 
			{
				st[prime1[i]*j-l]=1;
			}
		}	 //压缩储存,区间长度很小 
	}
	if(l==1) st[0]=1; 
}
void solve ()
{
	ll minn=INF,maxn=-INF;
	ll minl,minr,maxl,maxr;
	get_prime2();
	ll p=-1; 
	for(int i=0;i<=r-l;i++)
	{
		if(!st[i])//只需要记录前面和后面就可以了 
		{
			if(p!=-1) 
			{
				if(maxn<i-p) maxn=i-p,maxl=p,maxr=i;//类似神奇的幻方,只需要记录前一状态即可 
				if(minn>i-p) minn=i-p,minl=p,minr=i; 
			}
			p=i;//每次做完都要更新,而不是第一次更新,因为相邻 
		}
	}
	//通过状态有没有更新,来判断是否具有结果 
	if(maxn==-INF)printf("There are no adjacent primes.\n");
	else printf("%lld,%lld are closest, %lld,%lld are most distant.\n",minl+l,minr+l,maxl+l,maxr+l);
//	if(cnt2<=1) cout<<"There are no adjacent primes.\n";
//	else 
//	{
//		for(int i=0;i<cnt2;i++)
//		{
//			if(prime2[i+1]-prime2[i]<minn)
//			{
//				minn=prime2[i+1]-prime2[i];
//				minl=prime2[i],minnr=prime1[i+1];
//			}
//			if(prime2[i+1]-prime2[i]>maxn)
//			{
//				maxn=prime2[i+1]-prime2[i];
//				maxl=prime2[i],maxr=prime1[i+1];
//			}
//		}
//		printf("%lld,%lld are closest, %lld,%lld are most distant.\n",minl,minr,maxl,maxr);
//	}
}
int main()
{
	get_prime(N);
	while(~scanf("%lld%lld",&l,&r))solve();
	return 0;
}
 

  

标签:prime,distance,minl,ll,素数,POJ,INF,prime2,lld
来源: https://www.cnblogs.com/Astronaut0142/p/15065151.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有