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 : 3Prerequisites: Sieve of Eratosthenes, upper and lower boundUnderstanding : Semiprimes are numbers of the form
// 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:
Time Complexity: O(N*logN)3