#数论,线性筛,eratosthenes#poj 2689 Prime Distance

题目

在一个区间 [ l . . . r ] [l...r] [l...r],求两对相邻的质数,一对差值最大,一对最小(可以相同) ( 1 ≤ l ≤ r ≤ 2147483648 ( u n s i g n e d ) ) (1\leq l\leq r\leq 2147483648(unsigned)) (1lr2147483648(unsigned))


分析

然而直接跑绝对会TLE,但是可以用试除法的思想可以发现可以跑2到 r \sqrt r r 筛一筛(我选离线),然后每次询问筛一筛,就没有什么了,时间复杂度 O ( 47000 + ( r − l ) log ⁡ log ⁡ ( r − l ) ) O(47000+(r-l)\log \log(r-l)) O(47000+(rl)loglog(rl))


代码

#include <cstdio>
#include <bitset>
typedef unsigned uit;
uit prime[4793],v[46341],m,l,r;
int main(){
	for (register uit i=2;i<=46340;i++){//线性筛
		if (!v[i]) v[i]=i,prime[++m]=i;
		for (register uit j=1;j<=m;j++){
			if (prime[j]>v[i]||prime[j]>46340/i) break;
			v[i*prime[j]]=prime[j];
		}
    }
	while (scanf("%u%u",&l,&r)==2){//unsigned
		if (l==1) l=2; if (r==1) r=2;
	    std::bitset<1000010>v1; v1.reset();
		for (register uit j=1;j<=m;j++)
		for (register uit k=l/prime[j];k<=r/prime[j];k++)
		if (prime[j]*k>=l&&prime[j]*k<=r&&k>1) v1[prime[j]*k-l]=1; //欧式筛
		uit pri2=l,pri1,ans1=0,ans2=r-l<<1,a1,a2,b1,b2;
		while (v1[pri2-l]&&pri2<=r) pri2++;//找到较小的质数
		for (register uit j=pri2;j<=r;j=pri1){
			pri1=j+1;
			while (v1[pri1-l]&&pri1<=r) pri1++;//找较大的质数
			if (pri1<=r&&pri2<=r&&!v1[pri1-l]&&!v1[pri2-l]){
				if (ans1<pri1-pri2) ans1=pri1-pri2,a1=pri2,a2=pri1;
				if (ans2>pri1-pri2) ans2=pri1-pri2,b1=pri2,b2=pri1;
			}
			pri2=pri1;//更新较小的质数
		}
		if (!ans1) printf("There are no adjacent primes.\n");//不存在答案
		else printf("%d,%d are closest, %d,%d are most distant.\n",b1,b2,a1,a2);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值