题意:传送门
题解:
L
,
R
≤
2
31
L,R\le2^{31}
L,R≤231,素数筛根本打不到
1
e
9
1e9
1e9的范围,但是区间最多只有
1
e
6
1e6
1e6,有一个定理需要知道就是任何一个合数必定包含一个不超过
n
\sqrt {n}
n的质因子。可以打出
50000
50000
50000的质因数,然后枚举质数的倍数将
[
l
,
r
]
[l,r]
[l,r]区间中的合数筛去,最后从质数中找出答案即可。
复杂度分析:线性筛
O
(
50000
)
O(50000)
O(50000),每个倍数大约是
O
(
1
e
6
/
p
)
O(1e6/p)
O(1e6/p),也就是
1
e
6
∗
调
和
级
数
1e6*调和级数
1e6∗调和级数的大小,最后大约
1
e
7
1e7
1e7的复杂度可以过题。
c
o
d
e
:
code:
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=1e6,M=5e4+5;
int primes[M],cnt;
bool st[M];
bool flag[N];
ll su[N];
void get_primes(int n)
{
for(int i=2;i<n;i++){
if(!st[i])primes[cnt++]=i;
for(int j=0;j<cnt&&primes[j]*i<=n;j++){
st[primes[j]*i]=true;
if(i%primes[j]==0)break;
}
}
}
int main()
{
get_primes(50000);
ll l,r;
while(cin>>l>>r){
memset(flag,false,sizeof(flag));
for(int i=0;i<cnt;i++){
int p=primes[i];
for(ll j=max((l+p-1)/p*p,2ll*p);j<=r;j+=p){
flag[j-l]=true;
}
}
int tot=0;
for(int i=0;i<=r-l;i++){
if(!flag[i]&&i+l>1ll){
su[tot++]=i+l;
}
}
if(tot<2)puts("There are no adjacent primes.");
else{
int minp=0,maxp=0;
for(int i=0;i+1<tot;i++){
int d=su[i+1]-su[i];
if(d<su[minp+1]-su[minp])minp=i;
if(d>su[maxp+1]-su[maxp])maxp=i;
}
printf("%lld,%lld are closest, %lld,%lld are most distant.\n", su[minp], su[minp + 1], su[maxp], su[maxp + 1]);
}
}
return 0;
}