zoukankan      html  css  js  c++  java
  • [POJ2689]Prime Distance

    题目:Prime Distance

    传送门:http://poj.org/problem?id=2689

    分析:

    1. $ [L,R] $ 只有1e6,于是暴力写了个millRabin测试,时间复杂度大约$ O(N*k*logN) $然后Tle。

    2. 可以考虑一下二次筛法。$ [L,R] $ 中每一个合数一定包含一个不超过$ sqrt n $ 的质因子。

    3. 我们把$ [ 1,sqrt R ] $ 的质数筛出来。

    4. 再标记 $ i*p, i in [ [frac{L}{p}] , [frac{R}{p}] ] $ ,就是把$ [L,R] $之间的合数筛掉。这个常数很小,时间复杂度$ O(sum{frac{R-L}{p}}) $ 。 

    5. 剩下的就是质数啦。

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    const int INF=1<<30,maxN=50005;
    int pn,p[maxN],vis[1000007];
    void getPrime(){
        for(int i=2;i<maxN;++i){
            if(!vis[i])p[++pn]=i;
            for(int j=1;j<=pn && i*p[j]<maxN;++j){
                vis[i*p[j]]=true;
                if(i%p[j]==0)break;
            }
        }
    }
    void getPrimeInLR(const int &L,const int &R){
        memset(vis,0,sizeof(vis));int *use=vis-L;
        for(int i=1,sR=sqrt(R+0.5);i<=pn && p[i]<=sR;++i){
            int k=ceil((double)L/p[i]);if(k<=1)++k;
            for(int j=(LL)k*p[i];j>0 && j<=(LL)R;j+=p[i])use[j]=1;
        }
        if(L==1)vis[0]=1;
    }
    int main(){
        getPrime();
        for(int L,R;~scanf("%d%d",&L,&R);){
            int i=L,last=0,*use=vis-L;int mn0=0,mn1=INF,mx0=0,mx1=0;
            getPrimeInLR(L,R);
            for(;i<=R && !last;++i)if(!use[i])last=i;
            for(;i>0 && i<=R;++i)
                if(!use[i]){
                    if(i-last<mn1-mn0){mn1=i;mn0=last;}
                    if(i-last>mx1-mx0){mx1=i;mx0=last;}
                    last=i;
                }
            if(!mn0)puts("There are no adjacent primes.");
            else printf("%d,%d are closest, %d,%d are most distant.
    ",mn0,mn1,mx0,mx1);
        }
        return 0;
    }

    素数筛的常数计算:

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    const int INF=1<<30,maxN=50005;
    int pn,p[maxN],vis[1000007];
    void getPrime(){
        for(int i=2;i<maxN;++i){
            if(!vis[i])p[++pn]=i;
            for(int j=1;j<=pn && i*p[j]<maxN;++j){
                vis[i*p[j]]=true;
                if(i%p[j]==0)break;
            }
        }
    }
    int main(){
        double ans=0;
        getPrime();
        for(int i=1;i<pn;++i)
            printf("%d %lf
    ",i,ans+=1.0/p[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    linux 配置ssh免密码登陆本机
    Java连接mysql数据库并插入中文数据显示乱码
    新浪微博热门评论爬虫采集
    新浪微博热门评论抽取规则
    【MySql】Java 批量插入数据库addBatch
    算法设计题4.3 等差数列
    PHP setcookie() 函数
    Linux下用于查看系统当前登录用户信息 w命令
    Ubuntu 登录锐捷 网卡被禁用 网口灯不亮解决
    将 VMware 最小化到系统托盘
  • 原文地址:https://www.cnblogs.com/hjj1871984569/p/10367635.html
Copyright © 2011-2022 走看看