Cod sursa(job #1996631)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 2 iulie 2017 09:38:51
Problema Ciurul lui Eratosthenes Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

vector<int> Sieve(int n) {
    if (n <= 32) {
        vector<int> primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
        for (int i = 0; i < (int)primes.size(); ++i) {
            if (n < primes[i]) {
                primes.resize(i);
                break;
            }
        }
        return primes;
    }

    vector<int> primes = {2};
    vector<int> is_prime((n + 1) / 32 / 2 + 1);
    for (const int x: {3, 5, 7, 11, 13, 17, 19, 23, 29, 31}) {
        primes.push_back(x);
        vector<int> aux(x);
        for (int i = (x - 3) / 2; i < (x << 5); i += x) {
            aux[i >> 5] |= (1 << (i & 31));
        }
        for (int i = 0; i < x; ++i) {
            for (int j = i; j < (int)is_prime.size(); j += x) {
                is_prime[j] |= aux[i];
            }
        }
    }

    for (int i = 0; i < (int)is_prime.size(); ++i) {
        for (int j = ~is_prime[i]; j; j &= j - 1) {
            int x = i << 5 | __builtin_ctz(j & -j);
            int number = 2 * x + 3;
            if (number > n) {
                break;
            }

            primes.push_back(number);
            for (int i = x; 2 * i <= n; i += number) {
                is_prime[i >> 5] |= 1 << (i & 31);
            }
        }
    }
    return primes;
}

int main() {
#ifdef INFOARENA
    ifstream cin("ciur.in");
    ofstream cout("ciur.out");
#endif
    int n; cin >> n;
    cout << Sieve(n).size() << '\n';
}