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 = 10Output :2

4, 6, 9, 10 are semi primes. But 6, 10 are square free semi primes.

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

**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 <bits/stdc++.h>` `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 range` `int` `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 code` `int` `main()` `{` ` ` `int` `L = 10, R = 20;` ` ` ` ` `// Function call` ` ` `cout << semiPrimeCount(L, R);` ` ` ` ` `return` `0;` `}` |

**Output:**

3

**Time Complexity:** O(N*logN)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more, please refer **Complete Interview Preparation Course****.**