Exactly n distinct prime factor numbers from a to b - GeeksforGeeks
You are given two numbers a and b (1 <= a,b <= 10^8 ) and n. The task is to find all numbers between a and b inclusively having exactly n distinct prime factors. The solution should be designed in a way that it efficiently handles multiple queries for different values of a and b like in Competitive Programming.
Read full article from Exactly n distinct prime factor numbers from a to b - GeeksforGeeks
You are given two numbers a and b (1 <= a,b <= 10^8 ) and n. The task is to find all numbers between a and b inclusively having exactly n distinct prime factors. The solution should be designed in a way that it efficiently handles multiple queries for different values of a and b like in Competitive Programming.
This problem is basically application of segmented sieve. As we know that all prime factors of a number are always less than or equal to square root of number i.e; sqrt(n). So we generate all prime numbers less than or equals to 10^8 and store them in an array. Now using this segmented sieve we check each number from a to b to have exactly n prime factors.
// Stores all primes less than and equals to sqrt(10^8) = 10000vector <int> primes;// Generate all prime numbers less than or equals to sqrt(10^8)// = 10000 using sieve of sundaramvoid segmentedSieve(){ int n = 10000; // Square root of 10^8 // In general Sieve of Sundaram, produces primes smaller // than (2*x + 2) for a number given number x. // Since we want primes smaller than n=10^4, we reduce // n to half int nNew = (n-2)/2; // This array is used to separate numbers of the form // i+j+2ij from others where 1 <= i <= j bool marked[nNew + 1]; // Initalize all elements as not marked memset(marked, false, sizeof(marked)); // Main logic of Sundaram. Mark all numbers of the // form i + j + 2ij as true where 1 <= i <= j for (int i=1; i<=nNew; i++) for (int j=i; (i + j + 2*i*j) <= nNew; j++) marked[i + j + 2*i*j] = true; // Since 2 is a prime number primes.push_back(2); // Remaining primes are of the form 2*i + 1 such that // marked[i] is false. for (int i=1; i<=nNew; i++) if (marked[i] == false) primes.push_back(2*i+1);}// Function to count all numbers from a to b having exactly// n prime factorsint Nfactors(int a, int b, int n){ segmentedSieve(); // result --> all numbers between a and b having // exactly n prime factors int result = 0; // check for each number for (int i=a; i<=b; i++) { // tmp --> stores square root of current number because // all prime factors are always less than and // equal to square root of given number // copy --> it holds the copy of current number int tmp = sqrt(i), copy = i; // count --> it counts the number of distinct prime // factors of number int count = 0; // check divisibility of 'copy' with each prime less // than 'tmp' and divide it until it is divisible by // current prime factor for (int j=0; primes[j]<=tmp; j++) { if (copy%primes[j]==0) { // increment count for distinct prime count++; while (copy%primes[j]==0) copy = copy/primes[j]; } } // if number is completely divisible then at last // 'copy' will be 1 else 'copy' will be prime, so // increment count by one if (copy != 1) count++; // if number has exactly n distinct primes then // increment result by one if (count==n) result++; } return result;}