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;
}
本文来自博客园,作者:夏午Sharve,转载请注明原文链接:https://www.cnblogs.com/XiaWuSharve/p/15515482.html
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号