Cod sursa(job #1337100)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 8 februarie 2015 16:31:43
Problema Ciurul lui Eratosthenes Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.96 kb
#include <cstdio>
#include <cmath>
#include <stdint.h>
#include <cstring>

using namespace std;

#define SIZE ( 1 << 16 )
#define MAX_SQR ( 1 << 14 )

#define IN_FILE "ciur.in"
#define OUT_FILE "ciur.out"

inline uint_fast32_t f_sieve( const uint_fast32_t &N ) {
    register uint_fast32_t sqr = static_cast < int > ( sqrt( static_cast < float > ( N ) ) );
    register uint_fast32_t count = 1, s = 2, n = 3;
    char sieve[ SIZE ], prime[ MAX_SQR ] = { };
    uint_fast32_t primes[ MAX_SQR ], next[ MAX_SQR ];

    for( register uint_fast32_t i = 3; ( i * i ) <= sqr; i += 2 ) {
        if( !prime[ i ] ) {
            register uint_fast32_t i2 = i << 1;
            for( register uint_fast32_t j = i2 + i; j <= sqr; j += i2 )
                prime[ j ] = 1;
        }
    }

    for( register uint_fast32_t low = 0; low <= N; low += SIZE ) {
        memset( sieve, 0, SIZE );
        register uint_fast32_t high = ( low + SIZE - 1 < N ) ? low + SIZE - 1 : N;

        while( s * s <= high ) {
            if( !prime[ s ] ) {
                primes[ ++*primes ] = s;
                next[ ++*next ] = ( s * s ) - low;
            }
            ++s;
        }
        for( register uint_fast32_t i = 1; i <= *primes; ++i ) {
            register uint_fast32_t j = next[ i ];
            for( register uint_fast32_t k = ( primes[ i ] << 1 ); j < SIZE; j += k )
                sieve[ j ] = 1;
            next[ i ] = j - SIZE;
        }
        while( n <= high ) {
            if( !sieve[ n - low ] )
                ++count;
            n += 2;
        }
    }
    return count;
}
int main( ) {
    FILE *f;
    unsigned char c;
    uint_fast32_t N = 0;

    f = fopen( IN_FILE, "r" );
    c = fgetc( f );
    while( c != '\n' ) {
        N = ( N << 1 ) + ( N << 3 ) + ( c - '0' );
        c = fgetc( f );
    }
    fclose( f );

    f = fopen( OUT_FILE, "w" );
    fprintf( f, "%u\n", f_sieve( N ) );
    fclose( f );
    return 0;
}