📜  阶乘除数

📅  最后修改于: 2021-04-23 06:26:47             🧑  作者: Mango

给定数字n ,计算n个除数的总数

例子:

一个简单的解决方案是首先计算给定数的阶乘,然后计算阶乘的除数。该解决方案效率不高,并且可能会因阶乘计算而导致溢出。
更好的解决方案是基于Legendre的公式。步骤如下:

  1. 查找所有小于或等于n(输入数字)的质数。我们可以为此使用筛网算法。令n为6。所有小于6的质数均为{2,3,5}。
  2. 对于每个质数,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。
  3. 结果为(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