Найти все простые числа в диапазоне [A; B]

232
29 марта 2019, 21:00

Задача:

Найти все простые числа в диапазоне от А до В (1 <= A <= B <= 10^12 ), при условии, что В - А >= 10 ^ 6. Уже 4 день ломаю над этим голову. Есть решение на С++ с помощью Решета Эратосфена.

Решение:

#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const ll MAXN = 1e6 + 1;
int main() {
    cin.tie(0); //Ускоряем cin
    cout.tie(0); //Ускоряем cout
    ll a, b;
    cin >> a >> b; //Получаем числа
    bool prime[MAXN], ans[MAXN]; //ans[i] - является ли число a + i простым
    memset(prime, true, MAXN);
    memset(ans, true, MAXN);
    prime[0] = prime[1] = false;
    //Оба вложенных цикла взяты из кода по ссылку (стандартная реализация решета Эратосфена)
    ll n = MAXN - 1;
    for (ll i = 2; i <= n; ++i) {
        if (prime[i]) {
            ll r = a % i;
            r = (i - r) % i; //Что нужно прибавить к а, чтобы получить непростое число
            if (a + r > i && r < MAXN) //Проверяем на выход из массива. Если убрать условие а + r > i, тогда алгоритм отмечает 2, 3, 5 как не простые
                ans[r] = false;
            if (i + r < MAXN && a + r + i > 1ll * i)
                ans[i + r] = false;
            for (ll j = i * i; j <= n; j += i) {
                prime[j] = false;
                if (a <= j && j - a < MAXN) //Если а < 10 ^ 6 (бех этой проверки не работает)
                    ans[j - a] = false;
                if (j + r < MAXN)
                    ans[j + r] = false;
            }
        }
    }
    //Выводим результат
    for (ll i = 0; i <= b - a; ++i) {
        if (ans[i] && a + i >= 2)
            cout << a + i << ' ';
    }
}

Описание решения:

Находим все простые на отрезке [0; b - a] за О(10^6 log log 10^6), с помощью остатков от деления переносим эти простые на отрезок [a; b].

Проблема:

Решение не работает на каких-то тестах (т.е решение неполное). Тесты, к сожалению, неизвестны.

Answer 1

Начал проводить тесты на больших числах и заметил, что часто попадают 1-2 непростых. Не знаю почему, но замена j = i * i на j = 2 * i всё исправила, и программа не работала дольше 40 мс.

Полный код решения:

#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const ll MAXN = 1e6 + 1;
ll max(ll a, ll b) {
    return a > b ? a : b;
}
int main() {
    //cin.tie(0); //Ускоряем cin
    //cout.tie(0); //Ускоряем cout
    ll a, b;
    cin >> a >> b; //Получаем числа
    bool prime[MAXN], ans[MAXN]; //ans[i] - является ли число a + i простым
    memset(prime, true, MAXN);
    memset(ans, true, MAXN);
    prime[0] = prime[1] = false;
    ll mmax = MAXN - 1;
    for (ll i = 2; i <= mmax; ++i) {
        if (prime[i]) {
            ll r = a % i;
            r = (i - r) % i; //Что нужно прибавить к а, чтобы получить непростое число
            if (a + r > i && r < MAXN) //Проверяем на выход из массива. Если убрать условие а + r > i, тогда алгоритм отмечает 2, 3, 5 как не простые
                ans[r] = false;
            if (i + r < MAXN && a + r + i > i)
                ans[i + r] = false;
            for (ll j = 2 * i; j <= mmax; j += i) {
                prime[j] = false;
                if (a <= j && j - a < MAXN) //Если а < 10 ^ 6 (бех этой проверки не работает)
                    ans[j - a] = false;
                if (j + r < MAXN) {
                    ans[j + r] = false;
                }
            }
        }
    }
    //Выводим результат
    for (ll i = 0; i <= b - a; ++i) {
        if (ans[i] && a + i >= 2)
            cout << a + i << ' ';
    }
}
READ ALSO
Шифр Виженера(не работает)

Шифр Виженера(не работает)

решил сделать сам Шифратор/Дешифратор Виженера, но столкнулся с какой-то не понятной проблемой:

158
Исходный код Yandex speller

Исходный код Yandex speller

Где я могу найти исходный код Yandex speller, обыскал весь интернет, но не нашел, еще один вопрос есть ли yandex speller в качестве библиотеки для java?

173
Java, парсинг строки

Java, парсинг строки

Есть строка типа HaT523HaT524HaT525Подскажите, пожалуйста, как можно разбить эту строку так:

191
Caused by: java.lang.ArrayIndexOutOfBoundsException: 15 в простом случае

Caused by: java.lang.ArrayIndexOutOfBoundsException: 15 в простом случае

В чем ошибка-то? Он возмущается на строчки

212