数数到 N 正好有 5 个除数
给定一个正整数N ,任务是计算范围[1, N]中恰好有 5 个除数的整数个数。
例子:
Input: N = 18
Output: 1
Explanation:
From all the integers over the range [1, 18], 16 is the only integer that has exactly 5 divisors, i.e. 1, 2, 8, 4 and 16.
Therefore, the count of such integers is 1.
Input: N = 100
Output: 2
朴素方法:解决给定问题的最简单方法是迭代范围[1, N]并计算该范围内除数为5的整数。
时间复杂度: O(N 4/3 )
辅助空间: O(1)
有效的方法:上述方法也可以通过观察一个事实来优化,即恰好有5 个除数的数字可以用p 4的形式表示,其中p是素数,因为除数的数量正好是5 。请按照以下步骤解决问题:
- 通过使用埃拉托色尼筛法生成所有素数,使其四次方小于10 18并将其存储在向量中,例如A[] 。
- 初始化两个变量,比如低为0和高为A.size() – 1 。
- 为了执行二分搜索迭代直到低小于高并执行以下步骤:
- 找到mid的值作为(low + high)/2 。
- 在索引mid (mid – 1)处找到元素的四次方值,并将其存储在变量中,分别表示当前和上一个。
- 如果current的值为N ,则打印A[mid]的值作为结果。
- 如果current的值大于N并且previous最多为 N ,则打印A[mid]的值作为结果。
- 如果current的值大于N ,则将high的值更新为(mid – 1) 。否则,将low的值更新为(mid + 1) 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
#define ll long long int
const int MAX = 1e5;
using namespace std;
// Function to calculate the value of
// (x^y) using binary exponentiation
ll power(ll x, unsigned ll y)
{
// Stores the value of x^y
ll res = 1;
// Base Case
if (x == 0)
return 0;
while (y > 0) {
// If y is odd multiply
// x with result
if (y & 1)
res = (res * x);
// Otherwise, divide y by 2
y = y >> 1;
x = (x * x);
}
return res;
}
// Function to perform the Sieve Of
// Eratosthenes to find the prime
// number over the range [1, 10^5]
void SieveOfEratosthenes(
vector >& v)
{
bool prime[MAX + 1];
memset(prime, true, sizeof(prime));
prime[1] = false;
for (int p = 2; p * p <= MAX; p++) {
// If prime[p] is not changed
// then it is a prime
if (prime[p] == true) {
// Set all the multiples of
// p to non-prime
for (int i = p * 2;
i <= MAX; i += p)
prime[i] = false;
}
}
int num = 1;
// Iterate over the range [1, MAX]
for (int i = 1; i <= MAX; i++) {
// Store all the prime number
if (prime[i]) {
v.push_back({ i, num });
num++;
}
}
}
// Function to find the primes having
// only 5 divisors
int countIntegers(ll n)
{
// Base Case
if (n < 16) {
return 0;
}
// First value of the pair has the
// prime number and the second value
// has the count of primes till that
// prime numbers
vector > v;
// Precomputing all the primes
SieveOfEratosthenes(v);
int low = 0;
int high = v.size() - 1;
// Perform the Binary search
while (low <= high) {
int mid = (low + high) / 2;
// Calculate the fourth power of
// the curr and prev
ll curr = power(v[mid].first, 4);
ll prev = power(v[mid - 1].first, 4);
if (curr == n) {
// Return value of mid
return v[mid].second;
}
else if (curr > n and prev <= n) {
// Return value of mid-1
return v[mid - 1].second;
}
else if (curr > n) {
// Update the value of high
high = mid - 1;
}
else {
// Update the value of low
low = mid + 1;
}
}
return 0;
}
// Driver Code
int main()
{
ll N = 100;
cout << countIntegers(N);
return 0;
}
Java
// Java program for the above approach
import java.util.Vector;
public class GFG {
static int MAX = (int)1e5;
public static class pair {
long first;
long second;
pair(long first, long second)
{
this.first = first;
this.second = second;
}
}
// Function to calculate the value of
// (x^y) using binary exponentiation
static long power(long x, long y)
{
// Stores the value of x^y
long res = 1;
// Base Case
if (x == 0)
return 0;
while (y > 0)
{
// If y is odd multiply
// x with result
if ((y & 1) == 1)
res = (res * x);
// Otherwise, divide y by 2
y = y >> 1;
x = (x * x);
}
return res;
}
// Function to perform the Sieve Of
// Eratosthenes to find the prime
// number over the range [1, 10^5]
static void SieveOfEratosthenes(Vector v)
{
boolean prime[] = new boolean[MAX + 1];
for (int i = 0; i < prime.length; i++) {
prime[i] = true;
}
prime[1] = false;
for (int p = 2; p * p <= MAX; p++) {
// If prime[p] is not changed
// then it is a prime
if (prime[p] == true) {
// Set all the multiples of
// p to non-prime
for (int i = p * 2; i <= MAX; i += p)
prime[i] = false;
}
}
int num = 1;
// Iterate over the range [1, MAX]
for (int i = 1; i <= MAX; i++) {
// Store all the prime number
if (prime[i]) {
v.add(new pair(i, num));
num++;
}
}
}
// Function to find the primes having
// only 5 divisors
static long countIntegers(long n)
{
// Base Case
if (n < 16) {
return 0;
}
// First value of the pair has the
// prime number and the second value
// has the count of primes till that
// prime numbers
Vector v = new Vector<>();
// Precomputing all the primes
SieveOfEratosthenes(v);
int low = 0;
int high = v.size() - 1;
// Perform the Binary search
while (low <= high) {
int mid = (low + high) / 2;
// Calculate the fourth power of
// the curr and prev
long curr = power(v.get(mid).first, 4);
long prev = power(v.get(mid - 1).first, 4);
if (curr == n) {
// Return value of mid
return v.get(mid).second;
}
else if (curr > n && prev <= n) {
// Return value of mid-1
return v.get(mid - 1).second;
}
else if (curr > n) {
// Update the value of high
high = mid - 1;
}
else {
// Update the value of low
low = mid + 1;
}
}
return 0;
}
// Driver code
public static void main(String[] args)
{
long N = 100;
System.out.println(countIntegers(N));
}
}
// This code is contributed by abhinavjain194
输出:
2
时间复杂度: O(N*log N)
辅助空间: O(N)