Given an integer N. The task is to find minimum K such that the factorial of K is multiple of N. (2 ≤ N ≤ 1012)
Examples:
Input: N = 30
Output: 5
Explanation: 5! % 30 = 120 % 30 = 0, Therefore 5 is the answerInput: N = 280
Output: 7
Approach: To solve the problem follow the below idea:
- Binary Search can be used to solve this problem. Number of times number X! can be divided by Y is Z (for example 8 can be divided by 2, three times), Z = (X / Y) + (X / Y2) + (X / Y3) + (X / Y4) + ……………
- The idea is to first find all the prime divisors of N and their powers using a map data structure. Then, perform binary search to find the minimum value of K such that K! is a multiple of N and check if the mid value satisfies the condition or not by checking if every number that divides N compared with the mid value also divides mid, using the above formula.
- If the number of times N is divided by a prime divisor is greater than mid factorial, then mid factorial is not divisible by N, and return false else, returns true.
Below are the steps for the above approach:
- Declaring Hashmap mp[] to store divisors and their powers for number N.
- Declare low and high variables initially with values 2 and 1013.
- Write test() function that takes one parameter and returns a bool value whether the given number’s factorial is divisible by N.
- In the test, the function iterates all divisors of number N and checks whether those divisors also divide mid factorial which can be checked using the above number theory formula.
- Initialize the mid variable, mid = (low + high) / 2.
- Run a while loop till high – low > 1.
- check if the test function for the given mid value is true or not.
- if true set high to mid.
- else set low to mid + 1.
- After the while loop ends if the test function for low is true then return low else return high as the answer.
Below is the code for the above approach:
C++
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// To avoid overflow #define int long long // Check function of binary search bool test( int mid, map< int , int >& mp)
{ // Every number that divides N
// compared with Mid whether it
// also divides Mid
for ( auto & e : mp) {
// cnt stores number of times mid
// factorial can be divided with
// e.first (which is number that
// also divides N e.second times)
int cnt = 0;
// Iterating till power of 30
for ( int i = 1; i <= 30; i++) {
// Number theory formula
int temp = (mid / pow (e.first, i));
// If temp is zero we can
// break it out to speed
// up the program
if (temp == 0)
break ;
// Adding temp to count
cnt += temp;
}
// If number of times N is divided
// by e.first greater than mid
// factorial that means mid factorial
// is not divisible by N return false
if (e.second > cnt)
return 0;
}
// Otherwise return true
return 1;
} // Function to find minimum value of K // such that K! is multiple of N int findMinK( int N)
{ // Step 1 : Finding all prime divisors
// of N and their powers
// Hash map to store prime divisors
// with its powers
map< int , int > mp;
// Count the number of times 2 divides
int count = 0;
while (!(N % 2)) {
// N divide by 2
N /= 2;
// Increasing the counter
count++;
}
// If 2 divides it
if (count)
mp[2] = count;
// Check for all the possible numbers
// that can divide it
for ( int i = 3; i <= sqrt (N); i += 2) {
// Resetting count to zero
count = 0;
// Divide it until possible
while (N % i == 0) {
// Increasing the counter
count++;
// Divide it by i
N = N / i;
}
// If count is non zero then
if (count)
mp[i] = count;
}
// If n at the end is a prime number.
if (N > 2)
mp[N] = 1;
// Step 2 : Binary Search on answer K
// low pointer on 2 and high on
// maximum value
int low = 2, high = 1e13;
// While high is greater than to 1
while (high - low > 1) {
// mid value
int mid = (high + low) / 2;
// Checking for mid value
if (test(mid, mp)) {
high = mid;
}
else {
low = mid + 1;
}
}
// If check fucntion is true for
// low then return low
if (test(low, mp))
return low;
// Else return high
else
return high;
} // Driver Code int32_t main() { // Input 1
int N = 30;
// Function Call
cout << findMinK(N) << endl;
return 0;
} |
Java
// Java code to implement the approach import java.util.*;
class GFG {
// To avoid overflow
static long MAX_VALUE = ( long )1e13;
// Check function of binary search
static boolean test( long mid, Map<Long, Long> mp)
{
// Every number that divides N
// compared with Mid whether it
// also divides Mid
for (Map.Entry<Long, Long> e : mp.entrySet()) {
// cnt stores number of times mid
// factorial can be divided with
// e.getKey() (which is number that
// also divides N e.getValue() times)
long cnt = 0 ;
// Iterating till power of 30
for ( long i = 1 ; i <= 30 ; i++) {
// Number theory formula
long temp = ( long )Math.floor(
mid / Math.pow(e.getKey(), i));
// If temp is zero we can
// break it out to speed
// up the program
if (temp == 0 )
break ;
// Adding temp to count
cnt += temp;
}
// If number of times N is divided
// by e.getKey() greater than mid
// factorial that means mid factorial
// is not divisible by N return false
if (e.getValue() > cnt)
return false ;
}
// Otherwise return true
return true ;
}
// Function to find minimum value of K
// such that K! is multiple of N
static long findMinK( long N)
{
// Step 1 : Finding all prime divisors
// of N and their powers
// Hash map to store prime divisors
// with its powers
Map<Long, Long> mp = new HashMap<Long, Long>();
// Count the number of times 2 divides
long count = 0 ;
while (N % 2 == 0 ) {
// N divide by 2
N /= 2 ;
// Increasing the counter
count++;
}
// If 2 divides it
if (count != 0 )
mp.put(( long ) 2 , count);
// Check for all the possible numbers
// that can divide it
for ( long i = 3 ; i <= Math.sqrt(N); i += 2 ) {
// Resetting count to zero
count = 0 ;
// Divide it until possible
while (N % i == 0 ) {
// Increasing the counter
count++;
// Divide it by i
N /= i;
}
// If count is non zero then
if (count != 0 )
mp.put(i, count);
}
// If n at the end is a prime number.
if (N > 2 )
mp.put(N, ( long ) 1 );
// Step 2 : Binary Search on answer K
// low pointer on 2 and high on
// maximum value
long low = 2 , high = MAX_VALUE;
// While high is greater than to 1
while (high - low > 1 ) {
// mid value
long mid = (high + low) / 2 ;
// Checking for mid value
if (test(mid, mp)) {
high = mid;
}
else {
low = mid + 1 ;
}
}
// If check function is true for
// low then return low
if (test(low, mp))
return low;
// Else return high
else
return high;
}
// Driver Code
public static void main(String[] args)
{
// Input 1
int N = 30 ;
// Function Call
System.out.println(findMinK(N));
}
} // This code is contributed by prasad264 |
Python
import math
# Check function of binary search def test(mid, mp):
# Every number that divides N
# compared with Mid whether it
# also divides Mid
for e in mp.items():
# cnt stores number of times mid
# factorial can be divided with
# e.first (which is number that
# also divides N e.second times)
cnt = 0
# Iterating till power of 30
for i in range ( 1 , 31 ):
# Number theory formula
temp = mid / / math. pow (e[ 0 ], i)
# If temp is zero we can
# break it out to speed
# up the program
if temp = = 0 :
break
# Adding temp to count
cnt + = temp
# If number of times N is divided
# by e.first greater than mid
# factorial that means mid factorial
# is not divisible by N return False
if e[ 1 ] > cnt:
return False
# Otherwise return True
return True
# Function to find minimum value of K # such that K! is multiple of N def findMinK(N):
# Step 1 : Finding all prime divisors
# of N and their powers
# Hash map to store prime divisors
# with its powers
mp = {}
# Count the number of times 2 divides
count = 0
while N % 2 = = 0 :
# N divide by 2
N / / = 2
# Increasing the counter
count + = 1
# If 2 divides it
if count:
mp[ 2 ] = count
# Check for all the possible numbers
# that can divide it
for i in range ( 3 , int (math.sqrt(N)) + 1 , 2 ):
# Resetting count to zero
count = 0
# Divide it until possible
while N % i = = 0 :
# Increasing the counter
count + = 1
# Divide it by i
N / / = i
# If count is non zero then
if count:
mp[i] = count
# If n at the end is a prime number.
if N > 2 :
mp[N] = 1
# Step 2 : Binary Search on answer K
# low pointer on 2 and high on
# maximum value
low, high = 2 , int ( 1e13 )
# While high is greater than to 1
while high - low > 1 :
# mid value
mid = (high + low) / / 2
# Checking for mid value
if test(mid, mp):
high = mid
else :
low = mid + 1
# If check function is true for
# low then return low
if test(low, mp):
return low
# Else return high
else :
return high
# Driver Code if __name__ = = "__main__" :
# Input 1
N = 30
# Function Call
print (findMinK(N))
## This code is contributed by codearcade |
C#
// C# code to implement the approach using System;
using System.Collections.Generic;
class GFG
{ // Check function of binary search
static bool Test( long mid, Dictionary< int , int > mp)
{
// Every number that divides N
// compared with Mid whether it
// also divides Mid
foreach ( var e in mp)
{
// cnt stores the number of times mid
// factorial can be divided with
// e.Key (which is a number that
// also divides N e.Value times)
long cnt = 0;
// Iterating till power of 30
for ( int i = 1; i <= 30; i++)
{
// Number theory formula
long temp = mid / ( long )Math.Pow(e.Key, i);
// If temp is zero we can
// break it out to speed
// up the program
if (temp == 0)
break ;
// Adding temp to count
cnt += temp;
}
// If the number of times N is divided
// by e.Key is greater than mid
// factorial, that means mid factorial
// is not divisible by N, return false
if (e.Value > cnt)
return false ;
}
// Otherwise return true
return true ;
}
// Function to find the minimum value of K
// such that K! is a multiple of N
static long FindMinK( int N)
{
// Step 1 : Finding all prime divisors
// of N and their powers
// Dictionary to store prime divisors
// with their powers
Dictionary< int , int > mp = new Dictionary< int , int >();
// Count the number of times 2 divides
int count = 0;
while (N % 2 == 0)
{
// N divide by 2
N /= 2;
// Increasing the counter
count++;
}
// If 2 divides it
if (count > 0)
mp[2] = count;
// Check for all the possible numbers
// that can divide it
for ( int i = 3; i <= Math.Sqrt(N); i += 2)
{
// Resetting count to zero
count = 0;
// Divide it until possible
while (N % i == 0)
{
// Increasing the counter
count++;
// Divide it by i
N /= i;
}
// If count is non zero then
if (count > 0)
mp[i] = count;
}
// If N at the end is a prime number.
if (N > 2)
mp[N] = 1;
// Step 2 : Binary Search on answer K
// low pointer on 2 and high on
// maximum value
long low = 2, high = 10000000000000L;
// While high is greater than to 1
while (high - low > 1)
{
// mid value
long mid = (high + low) / 2;
// Checking for mid value
if (Test(mid, mp))
{
high = mid;
}
else
{
low = mid + 1;
}
}
// If the check function is true for
// low then return low
if (Test(low, mp))
return low;
// Else return high
else
return high;
}
// Driver Code
static void Main( string [] args)
{
// Input 1
int N = 30;
// Function Call
Console.WriteLine(FindMinK(N));
// Wait for user input to exit
Console.ReadLine();
}
} |
Javascript
// JavaScript code to implement the approach // Check function of binary search function test(mid, mp) {
// Every number that divides N
// compared with Mid whether it
// also divides Mid
for (let [key, value] of mp.entries()) {
// cnt stores number of times mid
// factorial can be divided with
// e.first (which is number that
// also divides N e.second times)
let cnt = 0;
// Iterating till power of 30
for (let i = 1; i <= 30; i++) {
// Number theory formula
let temp = Math.floor(mid / Math.pow(key, i));
// If temp is zero we can
// break it out to speed
// up the program
if (temp === 0) break ;
// Adding temp to count
cnt += temp;
}
// If number of times N is divided
// by e.first greater than mid
// factorial that means mid factorial
// is not divisible by N return false
if (value > cnt) return false ;
}
// Otherwise return true
return true ;
} // Function to find minimum value of K // such that K! is multiple of N function findMinK(N) {
// Step 1: Finding all prime divisors
// of N and their powers
// Hash map to store prime divisors
// with its powers
let mp = new Map();
// Count the number of times 2 divides
let count = 0;
while (N % 2 === 0) {
// N divide by 2
N /= 2;
// Increasing the counter
count++;
}
// If 2 divides it
if (count) mp.set(2, count);
// Check for all the possible numbers
// that can divide it
for (let i = 3; i <= Math.sqrt(N); i += 2) {
// Resetting count to zero
count = 0;
// Divide it until possible
while (N % i === 0) {
// Increasing the counter
count++;
// Divide it by i
N /= i;
}
// If count is non zero then
if (count) mp.set(i, count);
}
// If n at the end is a prime number.
if (N > 2) mp.set(N, 1);
// Step 2: Binary Search on answer K
// low pointer on 2 and high on
// maximum value
let low = 2,
high = 1e13;
// While high is greater than to 1
while (high - low > 1) {
// mid value
let mid = Math.floor((high + low) / 2);
// Checking for mid value
if (test(mid, mp)) {
high = mid;
} else {
low = mid + 1;
}
}
// If check function is true for
// low then return low
if (test(low, mp)) return low;
// Else return high
else return high;
} // Driver Code // Input 1 let N = 30; // Function Call console.log(findMinK(N)); |
Output
5
Time Complexity: O(sqrt(N) * log2(K))
Auxiliary Space: O(1)
Related Articles: