17. Power of k in factorial of n

βœ… GFG solution to find the highest power of k that divides n! using prime factorization and Legendre's formula. πŸš€

The problem can be found at the following link: πŸ”— Question Link

🧩 Problem Description

Given two positive integers n and k, determine the highest value of x such that k^x divides n! (n factorial) completely (i.e., n! % (k^x) == 0).

The task is to find the maximum power of k that can divide n! without leaving a remainder.

πŸ“˜ Examples

Example 1

Input: n = 7, k = 2
Output: 4
Explanation: 7! = 5040, and 2^4 = 16 is the highest power of 2 that divides 5040.

Example 2

Input: n = 10, k = 9
Output: 2
Explanation: 10! = 3628800, and 9Β² = 81 is the highest power of 9 that divides 3628800.

πŸ”’ Constraints

  • $1 \le n \le 10^5$

  • $2 \le k \le 10^5$

βœ… My Approach

The optimal approach uses Prime Factorization combined with Legendre's Formula to efficiently calculate the highest power of k that divides n!:

Prime Factorization + Legendre's Formula

  1. Prime Factorization of k:

    • Decompose k into its prime factors: k = p₁^a₁ Γ— pβ‚‚^aβ‚‚ Γ— ... Γ— pβ‚˜^aβ‚˜

    • For each prime factor pα΅’ with exponent aα΅’, we need to find how many times pα΅’ appears in n!

  2. Apply Legendre's Formula:

    • For each prime p, the highest power of p that divides n! is:

    • ⌊n/pβŒ‹ + ⌊n/pΒ²βŒ‹ + ⌊n/pΒ³βŒ‹ + ...

    • This counts how many multiples of p, pΒ², pΒ³, etc. are ≀ n

  3. Calculate Maximum Power:

    • For each prime factor pα΅’ with exponent aα΅’ in k:

    • Find legendre_count(n, pα΅’) using Legendre's formula

    • The contribution of this prime is legendre_count(n, pα΅’) / aα΅’

  4. Find Minimum:

    • The answer is the minimum of all contributions from prime factors

    • This ensures k^x divides n! for the maximum possible x

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(√k + Ξ£log_p n), where the sum is over all prime factors p of k. We factorize k in O(√k) time and apply Legendre's formula for each prime factor in O(log_p n) time.

  • Expected Auxiliary Space Complexity: O(1), as we only use a constant amount of additional space for variables, without storing the prime factors explicitly.

πŸ§‘β€πŸ’» Code (C++)

⚑ View Alternative Approaches with Code and Analysis

πŸ“Š 2️⃣ Iterative Prime Factorization

πŸ’‘ Algorithm Steps:

  1. Factor k by iterating through all potential divisors

  2. Calculate Legendre's formula inline for each prime

  3. Track minimum quotient across all prime factors

  4. Single-pass optimization for better cache locality

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(√k + log_p n) for each prime p

  • Auxiliary Space: πŸ’Ύ O(1) - constant space

βœ… Why This Approach?

  • Eliminates vector storage overhead

  • Better cache performance with inline calculations

  • Reduced memory allocations

πŸ“Š 3️⃣ Optimized Sieve-Based Approach

πŸ’‘ Algorithm Steps:

  1. Use trial division up to √k only

  2. Handle remaining prime factor efficiently

  3. Minimize function calls and loops

  4. Early termination when result becomes 0

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(√k + Ξ£log_p n) for primes p|k

  • Auxiliary Space: πŸ’Ύ O(1) - constant space

βœ… Why This Approach?

  • Early termination optimization

  • Long long prevents overflow in multiplication

  • Efficient prime factorization

πŸ“Š 4️⃣ Bit Manipulation Optimization

πŸ’‘ Algorithm Steps:

  1. Handle powers of 2 separately using bit operations

  2. Process odd factors with optimized loop

  3. Use bit shifts for efficient division by 2

  4. Combine results for final answer

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(√k + log n) optimized for powers of 2

  • Auxiliary Space: πŸ’Ύ O(1) - constant space

βœ… Why This Approach?

  • Efficient handling of powers of 2

  • Reduced iterations for odd numbers only

  • Built-in functions for bit counting

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

πŸ” Inline Factorization

🟒 O(√k + Σlog_p n)

🟒 O(1)

πŸš€ Minimal memory usage

πŸ’Ύ Repeated calculations

πŸ”Ί Iterative Optimization

🟒 O(√k + Σlog_p n)

🟒 O(1)

πŸ”§ Better cache locality

πŸ’Ύ Similar performance

⏰ Sieve-Based Early Exit

🟒 O(√k + Σlog_p n)

🟒 O(1)

πŸš€ Early termination

πŸ”„ Overflow handling needed

πŸ“Š Bit Manipulation

🟒 O(√k + log n)

🟒 O(1)

⚑ Optimized for powers of 2

πŸ”§ Complex bit operations

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

⚑ General purpose

πŸ₯‡ Inline Factorization

β˜…β˜…β˜…β˜…β˜…

πŸ“Š Large k values

πŸ₯ˆ Sieve-Based Early Exit

β˜…β˜…β˜…β˜…β˜†

🎯 Powers of 2 heavy

πŸ₯‰ Bit Manipulation

β˜…β˜…β˜…β˜…β˜†

πŸš€ Competitive programming

πŸ… Iterative Optimization

β˜…β˜…β˜…β˜…β˜…

πŸ§‘β€πŸ’» Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated