POJ2689 Prime Distance
目录
题目链接
知识点:质数筛、优化
题意
求 l l l到 r r r区间内所有的质数中相邻质数之差绝对值最大和最小值,并输出答案相同时质数小的质数
思路
1 到 2 31 的 质 数 筛 M L E , 注 意 到 区 间 长 度 不 超 过 1 6 1到2^{31}的质数筛MLE,注意到区间长度不超过1^6 1到231的质数筛MLE,注意到区间长度不超过16
预 处 理 出 不 超 过 2 31 的 质 数 筛 , 然 后 用 这 些 质 数 推 出 l 到 r 范 围 内 的 质 数 预处理出不超过\sqrt{2^{31}}的质数筛,然后用这些质数推出l到r范围内的质数 预处理出不超过231的质数筛,然后用这些质数推出l到r范围内的质数
存 储 l 到 r 范 围 内 的 质 数 把 l 的 下 标 设 为 0 , r 的 下 标 为 r − l 存储l到r范围内的质数把l的下标设为0,r的下标为r-l 存储l到r范围内的质数把l的下标设为0,r的下标为r−l
实现思路见代码。
代码
#include"cstdio"
#include"vector"
#include"bitset"
#include"algorithm"
#define ll long long
#define vec vector<ll>
#define pb push_back
#define all(a) (a).begin(),(a).end()
const ll N=2e5+10,M=1e6+10;
using namespace std;
vec preprime;//sqrt(1<<31)范围内的质数
bitset<M> notprime;
vec prime,dis;//prime:l到r的质数,dis:l到r的质数中相邻质数的距离
//预处理sqrt(1<<31)范围内的质数
void getprime() {
for(ll i=2; i<N; i++) {
if(!notprime[i]) preprime.pb(i);
for(ll j=0; j<preprime.size()&&i*preprime[j]<N; j++) {
notprime[i*preprime[j]]=true;
if(i%preprime[j]==0) break;
}
}
}
int main() {
ll l,r;
getprime();
while(~scanf("%lld%lld",&l,&r)) {
prime.resize(0);
notprime.reset();
if(l==1) notprime[0]=true;//区间包含1,1不是质数
//枚举sqrt(1<<31)范围内的质数,preprime[i]*preprime[i]解释见for内的注释,
//preprime[i]*preprime[i]>r时更大的质数没有贡献
for(int i=0; i<preprime.size()&&preprime[i]*preprime[i]<=r; i++) {
//枚举第i个质数的j倍;对于小于preprime[i]的倍数,交换质数和倍数的含义,
//发现之前已经枚举过了;(l-1)/preprime[i]+1 是 l/preprime[i] 的向上取整,
//最小的倍数;r/preprime[i]:最大的倍数
for(int j=max(preprime[i],(l-1)/preprime[i]+1); j<=r/preprime[i]; j++) {
notprime[j*preprime[i]-l]=true;
}
}
//筛出l到r的质数
for(int i=0; i<=r-l; i++) {
if(!notprime[i]) {
prime.pb(i+l);//记得还原
}
}
if(prime.size()<2) {
printf("There are no adjacent primes.\n");
continue;
}
dis.resize(prime.size()-1);
//计算距离
for(int i=0; i<prime.size()-1; i++) dis[i]=prime[i+1]-prime[i];
ll minans=dis[0],maxans=dis[0];
ll minindex,maxindex;
minindex=maxindex=0;
for(int i=0; i<dis.size(); i++) {
if(dis[i]<minans) {
minans=dis[minindex=i];
}
if(dis[i]>maxans) {
maxans=dis[maxindex=i];
}
}
printf("%lld,%lld are closest, %lld,%lld are most distant.\n",
prime[minindex],prime[minindex+1],prime[maxindex],prime[maxindex+1]);
}
return 0;
}