# Square free semiprimes in a given range using C++ STL

• Last Updated : 21 Aug, 2019

Given two integers L and R (L < = R). The task is to find all square free semiprimes in the range L to R (both inclusive).

Examples:

Input : L = 1, R = 10
Output : 2
4, 6, 9, 10 are semi primes. But 6, 10 are square free semi primes.

Input : L = 10, R = 20
Output : 3

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Prerequisites: Sieve of Eratosthenes, upper and lower bound

Understanding :
Semiprimes are numbers of the form where p and q are primes, not necessarily distinct. All semiprime has only 4 factors where p and q are the only two prime factors and .

Naive Approach:
Precompute all prime number upto . Find all combinations of two prime p and q such that is between L and R. Iterating through all combinations of prime would give a time complexity of . This solution, however, will not work for large L and R values.

Time Complexity: O(N^2)

Efficient Approach:
Precompute all prime number up to . We can divide the problem of finding two primes p and q into a simpler form.
As we can say that . Similarly as we can say that .
Now the problem is reduced to finding the count of q such that for all p.

Here, we can use binary search for finding upper_bound of from list of prime numbers and subtract it from index of lower_bound of from list of prime numbers to find the count of all q in range to for the given p. Repeating the above step for all prime p will give the answer for given range L to R

Below is the implementation of the above approach :

 // CPP program to find square free semiprimes in the range#include using namespace std;  #define N 78498  void Sieve(int pre[]){    // Max size of prime array    int MX = 1e6;      // Array of prime of size 1000001.    // will be marked true for prime, false otherwise    // i     = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...]    // prime = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, ...}    bool prime[MX + 1];      // i -> keeps track of index of prime     // (current integer)    // idx -> keeps track of index of pre    int i = 2;    int idx = 0;      // Initialize all entries to true    memset(prime, true, sizeof(prime));      // For all i from 2 to MX iterate    for (i = 2; i <= MX; i++)    {        // If i is prime        if (prime[i])         {            // Set idx'th index of pre as i and             // increment idx after setting the value            pre[idx++] = i;              // For all multiple of i from 2*i to MX            // mark them as false i.e. not prime            for (int j = (i << 1); j <= MX; j += i)                prime[j] = false;        }    }}  // Function to find square free semi primes in the rangeint semiPrimeCount(int L, int R){      // Array of prime integer    // will contain first 78498 primes    // idx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...]    // pre = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, ...}    int pre[N];      // Prepare pre array    Sieve(pre);      // Result of current query    int res = 0;      // Offset index from start    int j = 1;      // For all prime integers p in pre     // from 2 to sqrt(R) iterate    for (auto p : pre) {        // ub_num     = count of all multiple of p less         //             than R => p = R/p        //        // ub     = iterator of first element greater         //         than ub_num in pre        //        int ub_num = R / p;        auto ub = upper_bound(pre + j, pre + N, ub_num);          // lb_num     = count of all multiple of p         //             less than L => p = L/p        // If L is divisible by p increment p by         // 1 => p = p+1 = p+(L%p>0)        //        // lb     = iterator of first element greater         //         than or equal lb_num in pre              int lb_num = (L / p) + ((L % p) > 0);        auto lb = lower_bound(pre + j, pre + N, lb_num);          // Add the difference between ub and lb        res += ub - lb;          // Increment j        j++;          // If prime p is greater than or equal to sqrt(R)        if (p * p >= R)            break;    }    return res;}  // Driver codeint main(){    int L = 10, R = 20;          // Function call    cout << semiPrimeCount(L, R);      return 0;}

Output:

3


Time Complexity: O(N*logN)

My Personal Notes arrow_drop_up