给定数字n ,计算n个除数的总数! 。
例子:
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 12
一个简单的解决方案是首先计算给定数的阶乘,然后计算阶乘的除数。该解决方案效率不高,并且可能会因阶乘计算而导致溢出。
更好的解决方案是基于Legendre的公式。步骤如下:
- 查找所有小于或等于n(输入数字)的质数。我们可以为此使用筛网算法。令n为6。所有小于6的质数均为{2,3,5}。
- 对于每个质数,p找出除以n!的最大幂。为此,我们使用了勒让德公式。
除以p的最大幂的值为⌊n/p⌋+⌊n/(p 2 )⌋+⌊n/(p 3 )⌋+……
令这些值为exp1,exp2,exp3…。使用上面的公式,我们得到n = 6的以下值。- 2的最大幂除以6!,exp1 = 4。
- 3的最大幂除以6!,exp2 = 2。
- 5的最大幂除以6 !, exp3 = 1。
- 结果为(exp1 + 1)*(exp2 + 1)*(exp3 + 1)…对于所有质数,对于n = 6,值exp1,exp2和exp3分别为4 2和1(在上述步骤中计算) 2)。所以我们的结果是(4 +1)*(2 +1)*(1 +1)= 30
以下是上述想法的实现。
C++
// C++ program to find count of divisors in n!
#include
using namespace std;
typedef unsigned long long int ull;
// allPrimes[] stores all prime numbers less
// than or equal to n.
vector allPrimes;
// Fills above vector allPrimes[] for a given n
void sieve(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.
vector prime(n+1, true);
// Loop to update prime[]
for (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
for (int i=p*2; i<=n; i += p)
prime[i] = false;
}
}
// Store primes in the vector allPrimes
for (int p=2; p<=n; p++)
if (prime[p])
allPrimes.push_back(p);
}
// Function to find all result of factorial number
ull factorialDivisors(ull n)
{
sieve(n); // create sieve
// Initialize result
ull result = 1;
// find exponents of all primes which divides n
// and less than n
for (int i=0; i < allPrimes.size(); i++)
{
// Current divisor
ull p = allPrimes[i];
// Find the highest power (stored in exp)'
// of allPrimes[i] that divides n using
// Legendre's formula.
ull exp = 0;
while (p <= n)
{
exp = exp + (n/p);
p = p*allPrimes[i];
}
// Multiply exponents of all primes less
// than n
result = result*(exp+1);
}
// return total divisors
return result;
}
// Driver code
int main()
{
cout << factorialDivisors(6);
return 0;
}
Java
// JAVA program to find count of divisors in n!
import java.util.*;
class GFG
{
// allPrimes[] stores all prime numbers less
// than or equal to n.
static Vector allPrimes=new Vector();
// Fills above vector allPrimes[] for a given n
static void sieve(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.
boolean []prime=new boolean[n+1];
for(int i=0;i<=n;i++)
prime[i]=true;
// Loop to update prime[]
for (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
for (int i=p*2; i<=n; i += p)
prime[i] = false;
}
}
// Store primes in the vector allPrimes
for (int p=2; p<=n; p++)
if (prime[p])
allPrimes.add(p);
}
// Function to find all result of factorial number
static long factorialDivisors(int n)
{
sieve(n); // create sieve
// Initialize result
long result = 1;
// find exponents of all primes which divides n
// and less than n
for (int i=0; i < allPrimes.size(); i++)
{
// Current divisor
long p = allPrimes.get(i);
// Find the highest power (stored in exp)'
// of allPrimes[i] that divides n using
// Legendre's formula.
long exp = 0;
while (p <= n)
{
exp = exp + (n/p);
p = p*allPrimes.get(i);
}
// Multiply exponents of all primes less
// than n
result = result*(exp+1);
}
// return total divisors
return result;
}
// Driver code
public static void main(String []args)
{
System.out.println(factorialDivisors(6));
}
}
//This code is contributed by ihritik
Python3
# Python3 program to find count
# of divisors in n!
# allPrimes[] stores all prime
# numbers less than or equal to n.
allPrimes = [];
# Fills above vector allPrimes[]
# for a given n
def sieve(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.
prime = [True] * (n + 1);
# Loop to update prime[]
p = 2;
while(p * p <= n):
# If prime[p] is not changed,
# then it is a prime
if (prime[p] == True):
# Update all multiples of p
i = p * 2;
while(i <= n):
prime[i] = False;
i += p;
p += 1;
# Store primes in the vector allPrimes
for p in range(2, n + 1):
if (prime[p]):
allPrimes.append(p);
# Function to find all result of
# factorial number
def factorialDivisors(n):
sieve(n); # create sieve
# Initialize result
result = 1;
# find exponents of all primes
# which divides n and less than n
for i in range(len(allPrimes)):
# Current divisor
p = allPrimes[i];
# Find the highest power (stored in exp)'
# of allPrimes[i] that divides n using
# Legendre's formula.
exp = 0;
while (p <= n):
exp = exp + int(n / p);
p = p * allPrimes[i];
# Multiply exponents of all
# primes less than n
result = result * (exp + 1);
# return total divisors
return result;
# Driver Code
print(factorialDivisors(6));
# This code is contributed by mits
C#
// C# program to find count of divisors in n!
using System;
using System.Collections;
class GFG
{
// allPrimes[] stores all prime numbers less
// than or equal to n.
static ArrayList allPrimes = new ArrayList();
// Fills above vector allPrimes[] for a given n
static void sieve(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 = new bool[n+1];
for(int i = 0; i <= n; i++)
prime[i] = true;
// Loop to update prime[]
for (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
for (int i = p*2; i <= n; i += p)
prime[i] = false;
}
}
// Store primes in the vector allPrimes
for (int p = 2; p <= n; p++)
if (prime[p])
allPrimes.Add(p);
}
// Function to find all result of factorial number
static int factorialDivisors(int n)
{
sieve(n); // create sieve
// Initialize result
int result = 1;
// find exponents of all primes which divides n
// and less than n
for (int i = 0; i < allPrimes.Count; i++)
{
// Current divisor
int p = (int)allPrimes[i];
// Find the highest power (stored in exp)'
// of allPrimes[i] that divides n using
// Legendre's formula.
int exp = 0;
while (p <= n)
{
exp = exp + (n / p);
p = p * (int)allPrimes[i];
}
// Multiply exponents of all primes less
// than n
result = result * (exp + 1);
}
// return total divisors
return result;
}
// Driver code
public static void Main()
{
Console.WriteLine(factorialDivisors(6));
}
}
//This code is contributed by chandan_jnu
PHP
输出
30