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));

     
     

     

     

  • 相关阅读:
    Android--Service之AIDL传递复杂对象
    Android--广播BroadcastReceiver
    Android--拦截系统BroadcastReceiver
    Android--操作图片Exif信息
    Android--Activity的启动模式
    Android--Task和BackStack高级
    终于完成了Josephus的C语言实现啦~~
    如何将.SQL文件的数据导入到Mysql的数据库中
    什么情况下要加上【javascript:】
    路径的写法
  • 原文地址:https://www.cnblogs.com/vongang/p/2609659.html
Copyright © 2011-2022 走看看