zoukankan      html  css  js  c++  java
  • 给定范围的素数筛选(POJ 2689)

    问题:求L 到 R范围内的所有素数 (L < R <= 2147483647, R - L <= 10^6)

    解:要判断x是否是素数,可以看 x %(所有比x小的素数)是否有0出现。。。

    当然,还可以优化一下 x % (所有比sqrt(x)小的素数)

    已知 sqrt(2147483647) = 49361;

    打出 [2, 49361]范围内的素数表,大约不到5000个素数。

    然后用小于 sqrt(R)的素数乘上一个系数进行枚举,这样乘出来的数必然不是素数。把所有这些数筛小,剩下的就是素数了。

    至于这个系数怎么确定?可以知道这个系数的下限为 K = L/prime[i],当然,如果prime[i] >= L的话,K初始为2。其实就是K*prime[i]要保证大于L且离L最近

    打表:

        CL(vis, true);
        for(LL i = 2; i < N; ++i) {
            for(LL j = LL(i)*LL(i); j < N; j += i)  vis[j] = false;
        }
        n = 0;
        for(LL i = 2; i < N; ++i) {
            if(vis[i])  {
                prime[n++] = i;
            }
        }

    筛掉非素数:

    void get_p2(LL l, LL r) {
        LL i;
        LL k;
        if(r < N) {    //如果r <= 49361,直接用原来的素数表就可以
            i = 0;
            while(prime[i] < l) ++i;
            for(n2 = 0; prime[i] <= r; ++i)
                p2[n2++] = prime[i];
            return ;
        }
        CL(vis, true);
        for(i = 0; i < n && prime[i]*prime[i] <= r; ++i) {
            if(prime[i] >= l)   k = 2;
            else {
                k = l/prime[i];
                if(k*prime[i] < l)  ++k;
            }
            while(k*prime[i] <= r) {
                vis[k*prime[i] - l] = false;
                //printf("%lld %lld %d\n", k*prime[i], k*prime[i] - l, prime[i]);
                ++k;
            }
        }
        n2 = 0;
        for(i = 0; i <= r - l; ++i) {
            if(vis[i])  p2[n2++] = i + l;
        }
    }

    设原素数表有n个素数,k增长次数的平均数为ave(k),时间复杂度为O(n*ave(k));

     
     

     

     

  • 相关阅读:
    Fody is only supported on MSBuild 16 and above
    abp发送邮件AbpMailKit
    看一位老司机的博文,分享一下。
    nginx PC 移动配置
    微信开放平台登录
    flask 中 session的源码解析
    python mac环境搭建
    前端换mac可以参考搭一下简单的环境
    vue 导航钩子
    HTML5 History 模式
  • 原文地址:https://www.cnblogs.com/vongang/p/2609659.html
Copyright © 2011-2022 走看看