Cod sursa(job #2229223)

Utilizator inquisitorAnders inquisitor Data 6 august 2018 12:18:08
Problema Ciurul lui Eratosthenes Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.7 kb
#include <stdio.h>

unsigned primes[100000000 /8/4/3 + 1];

unsigned sieve(unsigned N)
{
    unsigned i, j, sqrt_N = __builtin_sqrtf(N), iBitNumber, iIndex, iBit, jBitNumber, jIndex, jBit, count = 2;

    for(i = 5; i <= sqrt_N; i += 4)
    {
        iBitNumber = i / 3 - 1, iIndex = iBitNumber >> 5, iBit = 1 << (iBitNumber & 31);

        if((primes[iIndex] & iBit) == 0)
        {
            for(j = i * i; j <= N; j += i << 2)
            {
                jBitNumber = j / 3 - 1;

                primes[jBitNumber >> 5] |= 1 << (jBitNumber & 31);

                j += i << 1;

                if(j >= N) break;

                jBitNumber = j / 3 - 1;

                primes[jBitNumber >> 5] |= 1 << (jBitNumber & 31);
            }
        }

        i += 2;

        iBit <<= 1;

        if((primes[iIndex] & iBit) == 0)
        {
            for(j = i * i; j <= N; j += i << 1)
            {
                jBitNumber = j / 3 - 1;

                primes[jBitNumber >> 5] |= 1 << (jBitNumber & 31);

                j += i << 2;

                if(j >= N) break;

                jBitNumber = j / 3 - 1;

                primes[jBitNumber >> 5] |= 1 << (jBitNumber & 31);
            }
        }
    }

    for(i = 5; i <= N; i += 6)
    {
        iBitNumber = i / 3 - 1, iIndex = iBitNumber >> 5, iBit   = (1 << (iBitNumber & 31));

        count += ((primes[iIndex] & (iBit     )) == 0);

        if(i < N) count += ((primes[iIndex] & (iBit << 1)) == 0);
    }

    return count;
}

int main()
{
    freopen("ciur.in", "r", stdin);
    freopen("ciur.out", "w", stdout);

    unsigned N; scanf("%u", &N);

    printf("%u ", sieve(N));

    return 0;
}