Given an integer n, determine the total number of positive divisors of n! (the factorial of n). Return the total number of divisors of n!.
Examples:
Input: n = 4
Output: 8
Explanation: 4! is 24. Divisors of 24 are 1, 2, 3, 4, 6, 8, 12 and 24.Input: n = 5
Output: 16
Explanation: 5! is 120. Divisors of 120 are 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 24 30, 40, 60 and 120.
Table of Content
[Naive Approach] Brute Force Approach - O(n!) Time and O(1) Space
The idea is to first compute the factorial of n and then count how many positive integers divide it exactly.
#include <iostream>
using namespace std;
// Function to return the total number of divisors of n!
int totalDivisors(int n)
{
// Compute n!
long long fact = 1;
for (int i = 2; i <= n; i++)
fact *= i;
// Count the divisors of n!
int count = 0;
for (long long i = 1; i <= fact; i++)
{
if (fact % i == 0)
count++;
}
return count;
}
int main()
{
int n = 4;
cout << totalDivisors(n) << endl;
return 0;
}
import java.util.*;
class GFG {
// Function to return the total number of divisors of n!
static int totalDivisors(int n)
{
// Compute n!
long fact = 1;
for (int i = 2; i <= n; i++)
fact *= i;
// Count the divisors of n!
int count = 0;
for (long i = 1; i <= fact; i++) {
if (fact % i == 0)
count++;
}
return count;
}
public static void main(String[] args)
{
int n = 4;
System.out.println(totalDivisors(n));
}
}
def totalDivisors(n):
# Compute n!
fact = 1
for i in range(2, n + 1):
fact *= i
# Count the divisors of n!
count = 0
for i in range(1, fact + 1):
if fact % i == 0:
count += 1
return count
# Driver Code
if __name__ == "__main__":
n = 4
print(totalDivisors(n))
using System;
class GFG {
// Function to return the total number of divisors of n!
static int totalDivisors(int n)
{
// Compute n!
long fact = 1;
for (int i = 2; i <= n; i++)
fact *= i;
// Count the divisors of n!
int count = 0;
for (long i = 1; i <= fact; i++) {
if (fact % i == 0)
count++;
}
return count;
}
static void Main()
{
int n = 4;
Console.WriteLine(totalDivisors(n));
}
}
// Function to return the total number of divisors of n!
function totalDivisors(n)
{
// Compute n!
let fact = 1n;
for (let i = 2n; i <= BigInt(n); i++)
fact *= i;
// Count the divisors of n!
let count = 0;
for (let i = 1n; i <= fact; i++) {
if (fact % i === 0n)
count++;
}
return count;
}
// Driver Code
const n = 4;
console.log(totalDivisors(n));
Output
8
[Better Approach] Using Prime Factorization - O(sqrt(n!)) Time and O(log(n!)) Space
Instead of checking every number from 1 to fact(n) to determine whether it is a divisor, we first find the prime factorization of fact(n). Once the exponent of each prime factor is known, the total number of divisors can be computed using the formula (e1+1)(e2+1)⋯⋯, where ei is the exponent of a prime factor.
- Compute the factorial of n.
- Find the prime factorization of fact(n) using trial division.
- Store the exponent of each prime factor in a map.
- Initialize the answer as 1.
- Multiply the answer by (exponent + 1) for every prime factor.
- Return the final answer.
#include <iostream>
#include <unordered_map>
using namespace std;
// Function to return the total number of divisors of n!
int totalDivisors(int n)
{
// Compute n!
long long fact = 1;
for (int i = 2; i <= n; i++)
fact *= i;
unordered_map<long long, int> primeFreq;
// Find the prime factorization of n!
for (long long i = 2; i * i <= fact; i++)
{
while (fact % i == 0)
{
primeFreq[i]++;
fact /= i;
}
}
// If a prime factor greater than sqrt(n!) remains
if (fact > 1)
primeFreq[fact]++;
int ans = 1;
// Calculate the total number of divisors
for (auto &it : primeFreq)
ans *= (it.second + 1);
return ans;
}
int main()
{
int n = 4;
cout << totalDivisors(n) << endl;
return 0;
}
import java.util.*;
class GFG {
// Function to return the total number of divisors of n!
static int totalDivisors(int n)
{
// Compute n!
long fact = 1;
for (int i = 2; i <= n; i++)
fact *= i;
HashMap<Long, Integer> primeFreq = new HashMap<>();
// Find the prime factorization of n!
for (long i = 2; i * i <= fact; i++) {
while (fact % i == 0) {
primeFreq.put(
i, primeFreq.getOrDefault(i, 0) + 1);
fact /= i;
}
}
// If a prime factor greater than sqrt(n!) remains
if (fact > 1)
primeFreq.put(
fact, primeFreq.getOrDefault(fact, 0) + 1);
int ans = 1;
// Calculate the total number of divisors
for (int exponent : primeFreq.values())
ans *= (exponent + 1);
return ans;
}
public static void main(String[] args)
{
int n = 4;
System.out.println(totalDivisors(n));
}
}
def totalDivisors(n):
# Compute n!
fact = 1
for i in range(2, n + 1):
fact *= i
primeFreq = {}
# Find the prime factorization of n!
i = 2
while i * i <= fact:
while fact % i == 0:
primeFreq[i] = primeFreq.get(i, 0) + 1
fact //= i
i += 1
# If a prime factor greater than sqrt(n!) remains
if fact > 1:
primeFreq[fact] = primeFreq.get(fact, 0) + 1
ans = 1
# Calculate the total number of divisors
for exponent in primeFreq.values():
ans *= (exponent + 1)
return ans
# Driver Code
if __name__ == "__main__":
n = 4
print(totalDivisors(n))
using System;
using System.Collections.Generic;
class GFG {
// Function to return the total number of divisors of n!
static int totalDivisors(int n)
{
// Compute n!
long fact = 1;
for (int i = 2; i <= n; i++)
fact *= i;
Dictionary<long, int> primeFreq
= new Dictionary<long, int>();
// Find the prime factorization of n!
for (long i = 2; i * i <= fact; i++) {
while (fact % i == 0) {
if (!primeFreq.ContainsKey(i))
primeFreq[i] = 0;
primeFreq[i]++;
fact /= i;
}
}
// If a prime factor greater than sqrt(n!) remains
if (fact > 1) {
if (!primeFreq.ContainsKey(fact))
primeFreq[fact] = 0;
primeFreq[fact]++;
}
int ans = 1;
// Calculate the total number of divisors
foreach(var item in primeFreq) ans
*= (item.Value + 1);
return ans;
}
static void Main()
{
int n = 4;
Console.WriteLine(totalDivisors(n));
}
}
// Function to return the total number of divisors of n!
function totalDivisors(n)
{
// Compute n!
let fact = 1n;
for (let i = 2n; i <= BigInt(n); i++)
fact *= i;
let primeFreq = new Map();
// Find the prime factorization of n!
for (let i = 2n; i * i <= fact; i++) {
while (fact % i === 0n) {
primeFreq.set(i, (primeFreq.get(i) || 0) + 1);
fact /= i;
}
}
// If a prime factor greater than sqrt(n!) remains
if (fact > 1n)
primeFreq.set(fact, (primeFreq.get(fact) || 0) + 1);
let ans = 1;
// Calculate the total number of divisors
for (let exponent of primeFreq.values())
ans *= (exponent + 1);
return ans;
}
// Driver Code
const n = 4;
console.log(totalDivisors(n));
Output
8
Note: This approach works correctly only for small values of n. In languages such as C++, Java, and C#, 21! exceeds the range of 64-bit integers, leading to overflow. Although Python (int) and JavaScript (BigInt) can handle larger factorials, explicitly computing and factorizing n! is still inefficient. Therefore, the expected approach using Legendre's Formula is recommended.
[Expected Approach] Using Legendre’s Formula and Sieve of Eratosthenes - O(n log(log n)) Time and O(n) Space
Instead of computing fact(n) explicitly, we directly compute the exponent of every prime in its prime factorization. Using Legendre's Formula, we can efficiently find how many times a prime p appears in fact(n). Once the exponents of all prime factors are known, the total number of divisors can be computed using the formula:
(a1+1)(a2+1)(a3+1)⋯ where a1, a2, a3, ... are the exponents of the prime factors of fact(n).
- Generate all prime numbers up to n using the Sieve of Eratosthenes.
- Initialize the answer as 1.
- Traverse each prime number p from 2 to n.
- Compute the exponent of p in fact(n) using Legendre's Formula by repeatedly adding ⌊n / p^k⌋ for increasing powers of p.
- Multiply the answer by (exponent + 1) for every prime.
- Return the final answer, which represents the total number of divisors of fact(n).
#include <iostream>
#include <vector>
using namespace std;
// Function to return the total number of divisors of n!
int totalDivisors(int n)
{
// Mark all numbers as prime initially.
vector<bool> isPrime(n + 1, true);
isPrime[0] = isPrime[1] = false;
// Generate all prime numbers up to n using
// the Sieve of Eratosthenes.
for (int i = 2; i * i <= n; i++)
{
if (isPrime[i])
{
for (int j = i * i; j <= n; j += i)
isPrime[j] = false;
}
}
int ans = 1;
// For every prime p, compute its exponent in n!
// using Legendre's Formula.
for (int p = 2; p <= n; p++)
{
if (!isPrime[p])
continue;
int exponent = 0;
long long power = p;
// Count the exponent of p in n!
while (power <= n)
{
exponent += n / power;
// Prevent overflow while computing p^k.
if (power > n / p)
break;
power *= p;
}
// Multiply by (exponent + 1) according to
// the divisor count formula.
ans *= (exponent + 1);
}
return ans;
}
int main()
{
int n = 4;
cout << totalDivisors(n) << endl;
return 0;
}
import java.util.*;
class GFG {
// Function to return the total number of divisors of n!
static int totalDivisors(int n)
{
// Mark all numbers as prime initially.
boolean[] isPrime = new boolean[n + 1];
Arrays.fill(isPrime, true);
isPrime[0] = false;
isPrime[1] = false;
// Generate all prime numbers up to n using
// the Sieve of Eratosthenes.
for (int i = 2; i * i <= n; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= n; j += i)
isPrime[j] = false;
}
}
int ans = 1;
// For every prime p, compute its exponent in n!
// using Legendre's Formula.
for (int p = 2; p <= n; p++) {
if (!isPrime[p])
continue;
int exponent = 0;
long power = p;
// Count the exponent of p in n!
while (power <= n) {
exponent += n / power;
// Prevent overflow while computing p^k.
if (power > n / p)
break;
power *= p;
}
// Multiply by (exponent + 1) according to
// the divisor count formula.
ans *= (exponent + 1);
}
return ans;
}
public static void main(String[] args)
{
int n = 4;
System.out.println(totalDivisors(n));
}
}
# Function to return the total number of divisors of n!
def totalDivisors(n):
# Mark all numbers as prime initially.
isPrime = [True] * (n + 1)
isPrime[0] = False
isPrime[1] = False
# Generate all prime numbers up to n using
# the Sieve of Eratosthenes.
i = 2
while i * i <= n:
if isPrime[i]:
j = i * i
while j <= n:
isPrime[j] = False
j += i
i += 1
ans = 1
# For every prime p, compute its exponent in n!
# using Legendre's Formula.
for p in range(2, n + 1):
if not isPrime[p]:
continue
exponent = 0
power = p
# Count the exponent of p in n!
while power <= n:
exponent += n // power
power *= p
# Multiply by (exponent + 1) according to
# the divisor count formula.
ans *= (exponent + 1)
return ans
# Driver Code
if __name__ == "__main__":
n = 4
print(totalDivisors(n))
using System;
class GFG {
// Function to return the total number of divisors of n!
static int totalDivisors(int n)
{
// Mark all numbers as prime initially.
bool[] isPrime = new bool[n + 1];
for (int i = 0; i <= n; i++)
isPrime[i] = true;
isPrime[0] = false;
isPrime[1] = false;
// Generate all prime numbers up to n using
// the Sieve of Eratosthenes.
for (int i = 2; i * i <= n; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= n; j += i)
isPrime[j] = false;
}
}
int ans = 1;
// For every prime p, compute its exponent in n!
// using Legendre's Formula.
for (int p = 2; p <= n; p++) {
if (!isPrime[p])
continue;
int exponent = 0;
long power = p;
// Count the exponent of p in n!
while (power <= n) {
exponent += (int)(n / power);
// Prevent overflow while computing p^k.
if (power > n / p)
break;
power *= p;
}
// Multiply by (exponent + 1) according to
// the divisor count formula.
ans *= (exponent + 1);
}
return ans;
}
static void Main()
{
int n = 4;
Console.WriteLine(totalDivisors(n));
}
}
// Function to return the total number of divisors of n!
function totalDivisors(n)
{
// Mark all numbers as prime initially.
let isPrime = new Array(n + 1).fill(true);
isPrime[0] = false;
isPrime[1] = false;
// Generate all prime numbers up to n using
// the Sieve of Eratosthenes.
for (let i = 2; i * i <= n; i++) {
if (isPrime[i]) {
for (let j = i * i; j <= n; j += i)
isPrime[j] = false;
}
}
let ans = 1;
// For every prime p, compute its exponent in n!
// using Legendre's Formula.
for (let p = 2; p <= n; p++) {
if (!isPrime[p])
continue;
let exponent = 0;
let power = p;
// Count the exponent of p in n!
while (power <= n) {
exponent += Math.floor(n / power);
// Prevent overflow while computing p^k.
if (power > Math.floor(n / p))
break;
power *= p;
}
// Multiply by (exponent + 1) according to
// the divisor count formula.
ans *= (exponent + 1);
}
return ans;
}
// Driver Code
let n = 4;
console.log(totalDivisors(n));
Output
8