zoukankan      html  css  js  c++  java
  • poj 2689 巧妙地运用素数筛选

    称号:

       给出一个区间[L,R]求在该区间内的素数最短,最长距离。 (R < 2 * 10^9 , R - L <= 10 ^ 6)

       由数论知识可得一个数的因子可在开根号内得到。

    所以,我们能够打出5*10^4内得素数。然后,在用一次筛法把在[L。R]内得合数找到,则剩下的就是素数了。这里要用到离散化。把一个数 x - L 保存在数组里。由于,直接保存肯定不行。可是我们发现区间特点较小。所以。能够想到离散化。

     

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 50000;
    int primes[MAXN];
    bool vst[MAXN];
    int notPrimes[1000010];
    int pos[1000010];
    int top,pcnt;
    
    void init(){
        top = 0;
        memset(vst,0,sizeof(vst));
        vst[0] = vst[1] = 1;
        for(int i = 2;i < MAXN;++i)if(!vst[i]){
            primes[top++] = i;
            for(int j = i + i;j < MAXN;j += i) vst[j] = 1;
        }
        //printf("top: %d
    ",top);
    }
    
    void solve(int L,int R){
        memset(notPrimes,0,sizeof(notPrimes));
    
        if(L == 1) L = 2;              /// 防止筛掉全部该区间的素数本身!!!!!
        for(int i = 0;i < top&&(LL)primes[i]*primes[i] <= R;++i){  //筛选因子
            int s = L / primes[i] + (L % primes[i] > 0); //当前素数的最小倍数达到L
           
            s = (s == 1 ? 2 : s);    /// 防止筛掉全部该区间的素数本身!!!!!
           
            for(int j = s;(LL)j*primes[i] <= R;++j){
                if((LL)j*primes[i] >= L)   //合数
                   notPrimes[j*primes[i] - L] = 1;   // 相当与离散化
            }
        }
    
        pcnt = 0;
        for(int i = 0;i <= R - L;++i){
            if(!notPrimes[i]){
                pos[pcnt++] = i + L;
                //printf("i -- > %d
    ",i + L);
            }
        }
        
        
        if(pcnt < 2){
            puts("There are no adjacent primes.");
        } else {
            int minl,minr,maxl,maxr,minv = 999999,maxv = -1;
            for(int i = 1;i < pcnt;++i){
                if(pos[i] - pos[i-1] > maxv){
                    maxv = pos[i] - pos[i-1];
                    maxl = pos[i-1];
                    maxr = pos[i];
                }
                if(pos[i] - pos[i-1] < minv){
                    minv = pos[i] - pos[i-1];
                    minl = pos[i-1];
                    minr = pos[i];
                }
            }
            printf("%d,%d are closest, %d,%d are most distant.
    ",minl,minr,maxl,maxr);
        }
    }
    int main()
    {
        init();
        int L,R;
        while(~scanf("%d%d",&L,&R)){
            solve(L,R);
        }
        return 0;
    }
    
    
    
    
    


     

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    djangorestframework的源码认证流程
    centos7 docker更换源地址(阿里云)
    vue 递归 无限极
    Linux文件属性及如何改变文件属性和权限
    centos7 安装docker
    centos7 mysql5.7 忘记密码
    git push 单个文件时超过100M报错,解决方案
    python中的依赖包--导出与安装
    18-----cmdb需求规划以及表结构设计
    17-----vue前端权限管理
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4728183.html
Copyright © 2011-2022 走看看