Cod sursa(job #1337124)

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

using namespace std;

#define SIZE ( 1 << 15 )
#define MAX_SQR ( 1 << 11 )

#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 = 3, n = 3, i2 = 9;
    char sieve[ SIZE ], prime[ MAX_SQR ] = { };
    uint_fast32_t primes[ MAX_SQR ], next[ MAX_SQR ];

    for( register uint_fast32_t i = 3; i2 <= sqr; ) {
        if( !prime[ i ] ) {
            for( register uint_fast32_t j = i2; j <= sqr; j += i )
                prime[ j ] = 1;
        }
        i += 2;
        i2 = ( i * i );
    }
    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 += 2;
        }
        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;
}