Prime Sieve
Sieve of Eratosthenes
void sieve(int32_t n) {
std::vector<bool> is_prime(n, true);
std::vector<int32_t> primes;
for (int64_t i = 2; i < n; ++i) {
if (!is_prime[i]) continue;
primes.push_back(i);
for (auto j = i * i; j < n; j += i) is_prime[j] = false;
}
}
Time Complexity:
The below analysis is for the case when the highlighted line above starts with j = 2 * i
.
To prove this, notice that the number of iterations are something like where is a prime. Well, Merten's Second Theorem states that
Linear Sieve
std::vector<int32_t> linear_sieve(int32_t n) {
std::vector<int32_t> primes;
std::vector<int32_t> lowest_prime(n, 0);
for (int64_t i = 2; i < n; ++i) {
if (lowest_prime[i] == 0) {
primes.push_back(i);
lowest_prime[i] = i;
}
for (auto const& p : primes) {
if (p > lowest_prime[i]) break;
if (auto j = i * p; j < n) {
lowest_prime[j] = p;
}
}
}
return lowest_prime;
}
Time Complexity:
Segmented Sieve
vector<int> prime_divisors[N];
/* assume sieve(N) is already called. */
void segmentedSieve(int a, int b) {
for (ll x = a; x <= b; ++x) prime_divisors[x - a].clear();
for (const auto& p: primes) {
for (ll x = ((a + p - 1) / p) * p; x <= b; x += p) {
/* p is a prime divisor of x. Do anything with this fact. */
prime_divisors[x - a].push_back(p);
}
}
}
/* If a prime greater than sqrt(N) divides x then that prime will be missing from prime_divisors[x].
* You can find that by the expressions x / (product of all p in prime_divisors[x])
*/