【ybtoj高效进阶6-2-2】质数距离

【ybtoj高效进阶6-2-2】质数距离

给出一道仅仅只是输出不同的题目:

【luogu P1835】 素数密度

题目大意:

给你一个区间,让你输出这个区间中找到两个相邻质数,令它们的差有最大值和最小值,输出这两个质数。
然后区间的左右端点 L , R < = 2 31 − 1 , R − L < = 1 0 6 L,R<=2^{31}-1,R-L<=10^6 L,R<=2311RL<=106

思路:

看到此题的第一个想法是求出区间 [ 1 , R ] [1,R] [1,R]的所有质数,然后在 [ L , R ] [L,R] [L,R]中寻找符合条件的质数。
然后 R < = 2 31 R<=2^{31} R<=231,最快的线性筛的时间复杂度也要 O ( N ) O(N) O(N),很明显也无法在规定时间内求出所有质数(当然打表除外)
但是我们不需要求出所有的质数,我们只关心 [ L , R ] [L,R] [L,R]中的所有质数,而我们知道,在筛法的过程中,每一个合数    x    ~~x~~   x  都会在 x \sqrt x x 之内被某一个数标记,那么这启发我们只需要求出 [ 1 , R ] [1,\sqrt R] [1,R ]的所有质数,然后用这些质数在区间 [ L , R ] [L,R] [L,R]将其所有的整数倍数进行标记,最后那些剩下的数就是质数了,然后把它们映射到一个下表为 [ 1 , p r i m e ( L , R ) ] [1,prime(L,R)] [1,prime(L,R)]的数组中, p r i m e ( L , R ) prime(L,R) prime(L,R)表示 [ L , R ] [L,R] [L,R]中质数的个数。
然后从前往后一个个判断即可。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
const ll V=1e7+10;
ll le,ri,p[V],ans[V],tot,n,top;
bool val[V],pd[V];
void get_prime()
{
	rep(i,2,n)
	{
		if(!val[i]) p[++top]=i;
		for(r ll j=1;i*p[j]<=n&&j<=top;++j)
		{
			val[i*p[j]]=true; 
			if(i%p[j]==0) break ;
		}
	}
}
int main()	
{
	while(scanf("%lld%lld",&le,&ri)!=EOF)
	{
		memset(p,0,sizeof(p));
		memset(val,false,sizeof(val));
		memset(ans,0,sizeof(ans));
		memset(pd,false,sizeof(pd));
		tot=top=0;
		n=sqrt(ri);
		get_prime();
		if(le==1) ++le;
		rep(i,1,top)
	 	 rep(j,(le-1)/p[i]+1,ri/p[i])
	  		 if(j>1) pd[j*p[i]-le]=true ;
		rep(i,le,ri)
	 	if(!pd[i-le]) ans[++tot]=i;
		if(tot<2)
		{
			printf("There are no adjacent primes.\n");
			continue ;
		}
		ll preb,pres,nowb,nows;
		preb=pres=ans[1],nowb=nows=ans[2];
		rep(i,3,tot)
		{
			if(ans[i]-ans[i-1]>nowb-preb)
			 preb=ans[i-1],nowb=ans[i];
			if(ans[i]-ans[i-1]<nows-pres)
			 pres=ans[i-1],nows=ans[i];
		}
		printf("%lld,%lld are closest, %lld,%lld are most distant.\n",pres,nows,preb,nowb);
	}
	
	
	return 0;
}


然后洛谷那道题就改一下输出就可以了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值