Smallest number S such that N is a factor of S factorial or S!
Given a number N. You are tasked with finding the smallest number S, such that N is a factor of S! (S factorial). N can be very large.
Examples:
Input : 6 Output : 3 The value of 3! is 6 This is the smallest number which can have 6 as a factor. Input : 997587429953 Output : 998957 If we calculate out 998957!, we shall find that it is divisible by 997587429953. Factors of 997587429953 are 998957 and 998629.
Naive Approach
We iterate from 1 to N, calculating factorial in each case. When we find a factorial that’s capable of having N as a factor, we output it. This method will be difficult to implement for large N, as the factorial can become very large.
Time Complexity: O(N^2)
Optimized Naive Approach
Instead of iterating from 1 to N, we use binary search. This is still a bad method, as we are still trying to calculate N!
Time Complexity O(N log N)
Optimum Solution
We can first calculate all the prime factors of N. We then reduce our problem to finding a factorial which has all the prime factors of N, at least as many times as they appear in N. We then binary search on elements from 1 to N. We can utilize Legendre’s Formula to check whether a number’s factorial has all the same prime factors. We then find the smallest such number.
C++
// Program to find factorial that N belongs to #include <bits/stdc++.h> using namespace std; #define ull unsigned long long // Calculate prime factors for a given number map<ull, int > primeFactors(ull num) { // Container for prime factors map<ull, int > ans; // Iterate from 2 to i^2 finding all factors for (ull i = 2; i * i <= num; i++) { while (num % i == 0) { num /= i; ans[i]++; } } // If we still have a remainder // it is also a prime factor if (num > 1) ans[num]++; return ans; } // Calculate occurrence of an element // in factorial of a number ull legendre(ull factor, ull num) { ull count = 0, fac2 = factor; while (num >= factor) { count += num / factor; factor *= fac2; } return count; } bool possible(map<ull, int > &factors, ull num) { // Iterate through prime factors for (map<ull, int >::iterator it = factors.begin(); it != factors.end(); ++it) { // Check if factorial contains less // occurrences of prime factor if (legendre(it->first, num) < it->second) return false ; } return true ; } // Function to binary search 1 to N ull search(ull start, ull end, map<ull, int > &factors) { ull mid = (start + end) / 2; // Prime factors are not in the factorial // Increase the lowerbound if (!possible(factors, mid)) return search(mid + 1, end, factors); // We have reached smallest occurrence if (start == mid) return mid; // Smaller factorial satisfying // requirements may exist, decrease upperbound return search(start, mid, factors); } // Calculate prime factors and search ull findFact(ull num) { map<ull, int > factors = primeFactors(num); return search(1, num, factors); } // Driver function int main() { cout << findFact(6) << "n" ; cout << findFact(997587429953) << "n" ; return 0; } |
Java
// Java Program to find factorial that N belongs to import java.util.HashMap; import java.util.Iterator; import java.util.Set; class Test { // Calculate prime factors for a given number static HashMap<Long, Integer> primeFactors( long num) { // Container for prime factors HashMap<Long, Integer> ans = new HashMap<Long, Integer>(){ @Override public Integer get(Object key) { if (containsKey(key)){ return super .get(key); } return 0 ; } }; // Iterate from 2 to i^2 finding all factors for ( long i = 2 ; i * i <= num; i++) { while (num % i == 0 ) { num /= i; ans.put(i, ans.get(i)+ 1 ); } } // If we still have a remainder // it is also a prime factor if (num > 1 ) ans.put(num, ans.get(num)+ 1 );; return ans; } // Calculate occurrence of an element // in factorial of a number static long legendre( long factor, long num) { long count = 0 , fac2 = factor; while (num >= factor) { count += num / factor; factor *= fac2; } return count; } static boolean possible(HashMap<Long, Integer> factors, long num) { Set<Long> s = factors.keySet(); // Iterate through prime factors Iterator<Long> itr = s.iterator(); while (itr.hasNext()) { long temp = itr.next(); // Check if factorial contains less // occurrences of prime factor if (legendre(temp, num) < factors.get(temp)) return false ; } return true ; } // Method to binary search 1 to N static long search( long start, long end, HashMap<Long, Integer> factors) { long mid = (start + end) / 2 ; // Prime factors are not in the factorial // Increase the lowerbound if (!possible(factors, mid)) return search(mid + 1 , end, factors); // We have reached smallest occurrence if (start == mid) return mid; // Smaller factorial satisfying // requirements may exist, decrease upperbound return search(start, mid, factors); } // Calculate prime factors and search static long findFact( long num) { HashMap<Long, Integer> factors = primeFactors(num); return search( 1 , num, factors); } // Driver method public static void main(String args[]) { System.out.println(findFact( 6 )); System.out.println(findFact(997587429953L)); } } // This code is contributed by Gaurav Miglani |
Output:
3 998957
At no point do we actually calculate a factorial. This means we do not have to worry about the factorial being too large to store.
Lagrange’s Formula runs in O(Log N).
Binary search is O(Log N).
Calculating prime factors is O(sqrt(N))
Iterating through prime factors is O(Log N).
Time complexity becomes: O(sqrt(N) + (Log N)^3)
This article is contributed by Aditya Kamath. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Recommended Posts:
- Smallest number with at least n digits in factorial
- Smallest number with at least n trailing zeroes in factorial
- Count all the numbers in a range with smallest factor as K
- Find the total number of composite factor for a given number
- N-th prime factor of a given number
- Factor Tree of a given Number
- k-th prime factor of a given number
- Find largest prime factor of a number
- Sum of largest prime factor of each number less than equal to n
- Find sum of a number and its maximum prime factor
- Largest factor of a given number which is a perfect square
- Find the last digit when factorial of A divides factorial of B
- C Program for factorial of a number
- Sum of divisors of factorial of a number
- First digit in factorial of a number
Improved By : nidhi_biet