版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugar_free_mint/article/details/82024372
题目
在一个区间 ,求两对相邻的质数,一对差值最大,一对最小(可以相同)
分析
然而直接跑绝对会TLE,但是可以用试除法的思想可以发现可以跑2到 筛一筛(我选离线),然后每次询问筛一筛,就没有什么了,时间复杂度
代码
#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;
}