Erastothenes c++ SPOJ的分段筛

Segmented Sieve of Erastothenes C++ SPOJ

本文关键字:分段 SPOJ c++ Erastothenes      更新时间:2023-10-16

我知道以前有人问过这个问题,但是我不能完全理解如何实现埃拉托色尼的分段筛。

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

我的方法

我可以实现埃拉托色尼筛法我可以找到最大到根号n的质数。但我不能理解如何实现"抵消",正在讨论在其他网站。如何在选定分区上执行筛检?

#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;
}

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

请注意,下面的代码将消除所有与素数p"对应"的合数。

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

将此思想推广到所有素数<= sqrt(b) .

首先,既然您提到您正在为SPOJ编码,那么我要告诉您这是行不通的。即使你有一个方法只从m到n执行SOE,你也要执行这样的服务t次,这将给你TLE。

期望的是在整个范围内对SOE进行简单的预计算,即从1到10^x。首先在while循环外执行SOE并将所有质数存储到vector中。然后在while循环中显示vector中所需的素数。