Сегментированное решето Эрастотена C ++ SPOJ

Я знаю, что об этом уже спрашивали, но я не могу полностью понять, как реализовать сегментированное решето Эратосфена.

Проблема

Ввод начинается с количества t тестов в единственной строке (t ‹= 10). В каждой из следующих t строк есть два числа 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;
}

person user3125772    schedule 30.05.2014    source источник
comment
Начать с числа, отличного от 1? Также научитесь правильно форматировать свой код.   -  person Bartek Banachewicz    schedule 30.05.2014
comment
См. Мой ответ здесь.   -  person user448810    schedule 30.05.2014


Ответы (2)


Рассмотрим отрезок S: [a, b] и простое число p.

Обратите внимание, что следующий код удалит все составные части, "соответствующие" простому p.

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

Распространите эту идею на все простые числа ‹= sqrt(b).

person preetsaimutneja    schedule 30.05.2014

Прежде всего, поскольку вы упомянули, что пишете для SPOJ, я скажу вам, что это не сработает. Даже если у вас каким-то образом есть способ выполнять SOE только от m до n, вы будете выполнять такие сеансы t раз, что даст вам TLE.

Ожидается простое предварительное вычисление SOE во всем диапазоне, то есть от 1 до 10 ^ x. Сначала за пределами цикла while выполните SOE и сохраните все простые числа в векторе. Затем в вашем цикле while просто отобразите необходимые простые числа из вектора.

person Kartik_Koro    schedule 30.05.2014
comment
Я использовал логический массив primes для просеивания и вектор prime для хранения / предварительного вычисления простых чисел for (i = m; i ‹= n; i ++) {if (primes [i] == true) {prime.push_back (i); // cout ‹< i ‹< \ t; }} длинные размеры = prime.size (); for (i = 0; i ‹sizes; i ++) {if (prime [i]› = m && prime [i] ‹= n) cout ‹< prime [i] ‹---------------- \ n; если (простое [i] ›n) разорвать; } // 'Я пробовал это, но это не сработало. Как это реализовать на самом деле? (Работает до 10 ^ 5 и не работает для больших значений m и n) - person user3125772; 30.05.2014
comment
Верните все простые числа в свой вектор за пределами цикла while. Внутри цикла while просто просматривайте вектор, пока не найдете простое ›m, и печатайте, пока не найдете простое› n. Вероятно, он работает только до 10 ^ 5 для вас, потому что вы где-то используете int, используйте long long int везде, где все должно быть в порядке. Следует отметить, что иногда компилятор вашего компьютера не позволяет вам создать массив bool размером 1000000000 для сита, но spoj позволит вам, я делал это раньше, я тестировал на ideone только что, создание такие большие массивы разрешены. ideone.com/qX2LNP - person Kartik_Koro; 30.05.2014
comment
У меня ошибка времени выполнения. Не работает для больших чисел ... ideone.com/cAhNWh - person user3125772; 30.05.2014