最多为 N 且只有 4 个因子或除数的数字计数
给定一个整数N ,找出小于或等于N且有 4 个因子的自然数的个数。
例子:
Input: N = 8
Output: 2
Explanation: {1} is divisor set of 1
{1, 2} is divisor set of 2
{1, 3} is divisor set of 3
{1, 2, 4} is divisor set of 4
{1, 5} is divisor set of 5
{1, 2, 3, 6} is divisor set of 6
{1, 7} is divisor set of 7
{1, 2, 4, 8} is divisor set of 8
So, 6 and 8 are only natural numbers less than or equal to N and count of divisors 4.
Input: N = 2
Output: 0
方法:解决问题的想法基于以下观察:
- Any number M can be written in form M = p1e1 * p2e2 * . . . where (p1, p2 . . .) are primes and (e1, e2 . . .) are respective exponents.
- The total number of factors of M is therefore (e + 1)*(e + 1)* . . .
- From above points, for the count of divisors of a natural number to be 4, there are two cases:-
- Case-1: N = p1 * p2 (where p1 and p2 are two distinct prime numbers)
- Case-2: N = p3 (where p is a prime number)
- So there must be two primes whose multiplication is less than N or one prime whose cube is less than N.
请按照以下步骤解决问题:
- 使用埃拉托色尼筛法找出所有小于或等于N的素数。
- 对于Case-1遍历所有素数并使用二进制搜索来查找乘积最多为N的多个素数。
- 对于Case-2 ,进行二分搜索以查找立方数小于或等于N的素数的数量。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find primes <= N
vector SieveOfEratosthenes(int n)
{
// Create a boolean array
// "prime[0..n]" and initialize
// all entries it as true.
// A value in prime[i] will
// finally be false if i is
// Not a prime, else true.
bool prime[n + 1];
memset(prime, true, sizeof(prime));
for (long long int p = 2;
p * p <= n; p++) {
// If prime[p] is not changed,
// then it is a prime
if (prime[p] == true) {
// Update all multiples
// of p greater than or
// equal to the square of it
for (long long int i = p * p;
i <= n; i += p)
prime[i] = false;
}
}
// Vector for storing prime number
// less than or equal to N
vector primes;
// Store all prime numbers
for (int p = 2; p <= n; p++)
if (prime[p])
primes.push_back(p);
return primes;
}
// Find floor of cube root of N
int primeCubic(vector& primes, int N)
{
// Val stores cube root of N
long long int l = 0, r = N, mid, val;
// Binary search loop for finding
// floor of cube root of N
while (l <= r) {
mid = (l + r) / 2;
if ((mid * mid * mid) <= N) {
val = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
// Iterator for finding index with
// value just greater than Val in primes
auto it = upper_bound(primes.begin(),
primes.end(), val);
it--;
return (it - primes.begin() + 1);
}
// Function to find primes with product <= N
int primeProduct(vector& primes,
int N)
{
// Stores the answer
int answer = 0;
// Iterator storing pointer to
// current prime
auto cur = primes.begin();
// Loop for traversing all primes
// Find number of indices less than
// current indices for which product
// is less than or equal to N
for (auto i : primes) {
long long int add
= upper_bound(primes.begin(),
cur, (N / i))
- primes.begin();
answer += add;
cur++;
}
return answer;
}
// Function to find the total count
int print(int N)
{
vector primes
= SieveOfEratosthenes(N);
int answer = 0;
answer += primeCubic(primes, N);
answer += primeProduct(primes, N);
return answer;
}
// Driver code
int main()
{
int N = 8;
// Print function Call
cout << print(N);
return 0;
}
输出
2
时间复杂度: O(N * log(logN) + N + logN) ≈ O(N * log (logN))
辅助空间: O(N)