Cod sursa(job #2229760)

Utilizator inquisitorAnders inquisitor Data 8 august 2018 03:30:35
Problema Ciurul lui Eratosthenes Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include <stdio.h>

#define N_MAX 2000000
#define  DIV 5
#define BITS 32
#define  MOD (BITS - 1)

unsigned p[N_MAX / 3 / BITS + 1];

unsigned sieve(unsigned n)
{
    register unsigned i, j, iBitNumber, iIndex, iBit, jBitNumber, jIndex, jBit, count = 2;

    for(i = 5; i * i <= n; i += 4)
    {
        iBitNumber = i / 3 - 1, iIndex = iBitNumber >> DIV, iBit = 1 << (iBitNumber & MOD);

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

                p[jBitNumber >> DIV] |= 1 << (jBitNumber & MOD);

                j += i << 1;

                if(j >= n) break;

                jBitNumber = j / 3 - 1;

                p[jBitNumber >> DIV] |= 1 << (jBitNumber & MOD);
            }
        }

        i += 2;

        iBit <<= 1;

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

                p[jBitNumber >> DIV] |= 1 << (jBitNumber & MOD);

                j += i << 2;

                if(j >= n) break;

                jBitNumber = j / 3 - 1;

                p[jBitNumber >> DIV] |= 1 << (jBitNumber & MOD);
            }
        }
    }

    for(i = 0; i <= n / 3 / BITS; i++)
    {
        count += BITS - __builtin_popcount(p[i]);
    }

    return count - __builtin_popcount(~((1 << (((n + 2) / 3 - 1) & MOD)) - 1));
}

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

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

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

    return 0;
}