• + 0 comments

    int solve(long long n, long long m) { // Prime flags in the interval between n and m // It's like Eratosthenes sieve but with offset vector intervalNumbers(m - n + 1, true); if (intervalNumbers.size() < 2) { return 0; } if (n == 1) { intervalNumbers[0] = false; }

    // Eratosthenes sieve from 0 to square root of m
    const int lim = sqrt(m);
    vector<bool> eratosthenesSieve(lim + 1, true);
    eratosthenesSieve[0] = false;
    eratosthenesSieve[1] = false;
    
    // Set flags + add primes to vector
    vector<long long> primes;
    for(int i = 2; i <= lim; ++i) {
        if(eratosthenesSieve[i]) {
            primes.push_back(i);
            for(int j = i * 2; j <= lim; j += i) {
                eratosthenesSieve[j] = false;
                if ( (j >= n) && (j <= m) ) {
                    intervalNumbers[j - n] = false;
                }
            }
        }
    }
    
    // Set flags for the interval 
    for(const long long i: primes) {
        for(int j = max(i * 2, (n + i  - 1) / i * i); j <= m; j += i) {
            intervalNumbers[j - n] = false;            
        }
    }
    
    // Calculating
    long long int twinCount = 0;
    for(size_t i = 0 ; i < intervalNumbers.size() - 2; ++i) {
        if(intervalNumbers[i] && intervalNumbers[i + 2]) {
            ++twinCount;
        }
    } 
    
    return twinCount;
    

    }