Eratosthenes C ++ SPOJ的分段筛

时间:2014-05-30 12:10:37

标签: c++ primes sieve-of-eratosthenes

我之前已经问过这个问题,但我无法完全理解如何实施Eratosthenes的分段筛。

问题

输入以单行中的测试用例的数量t开始(t <= 10)。在接下来的t行中的每一行中,存在由空格分隔的两个数m和n(1 <= m <= n <= 1000000000,n-m <= 100000)。对于每个测试用例,打印所有质数p,使得m <= p <= n,每行一个数,由空行分隔的测试用例。

我的方法

我可以实现Eratosthenes的Sieve,我可以找到n的平方根的素数。 但是我无法理解如何实现&#34;偏移&#34;正在其他网站上讨论。如何在选定的分区上执行Sieve?

#include <stdio.h>
#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    int t;
    cin>>t;

    while(t--)
    {
        long long m,n;
        long long p[100001];
        bool primes[100000];

        cin>>m;
        cin>>n;
        long long square=sqrt(n);
        cout<<square;
        int j=0;
        int i;
        primes[0]=false;    
        primes[1]=false;

        for(i=2; i<n;i++)
            primes[i]=true;

        for(i=2; i<=square; i++)
        {
            if(primes[i]==true)
            {
                for(j=i+i; j<=n; j+=i)
                    primes[j]=false;
            }
        }

        for(i=m; i<n ; i++)
        {
            if(primes[i]==true)
            {
                cout<<i<<" \t";
                if(i >= m)
                {
                    p[j]=i;
                    j++;
                }
            }
        }

        for(i=0 ; i<j ; i++)
        {
            cout<<p[i]<<"\n";
        }
    }

    return 0;
}

2 个答案:

答案 0 :(得分:1)

考虑段S:[a,b]和素数p。

请注意,以下代码将消除所有复合词“对应”素数p。

for(int i=ceil(a/p);i<=floor(b/p);++i) {
    new_primes[i*p-a]=false;

为所有素数扩展这个想法&lt; = sqrt(b)

答案 1 :(得分:0)

首先,既然你提到你正在为SPOJ编码,我会告诉你这不会起作用。即使你以某种方式获得了从m到n做SOE的方法,你也会进行t次这样的seof,这会给你TLE。

所考虑的是在整个范围内的简单的SOE预计算,即从1到10 ^ x。首先在while循环之外执行SOE并将所有素数存储到向量中。然后在你的while循环中,只需从向量中显示所需的素数。