Given two integers N and M, the task is to perform the following operations:
- For every value in the range [N, M], calculate the sum of its prime factors followed by the sum of prime factors of that sum and so on.
- Generate the above sequence for each array element and calculate the length of the sequence
Illustration
N = 8
Prime factors = {2, 2, 2}. Sum = 2 + 2 + 2 = 6.
Prime factors of 6 = {2, 3}. Sum = 2 + 3 = 5.
Now 5 cannot be reduced further.
Therefore, the sequence is {8, 6, 5}. The length of the sequence is 3.
- Find the maximum length of such subsequence generated.
Examples:
Input: N = 5, M = 10
Output: 3
Explanation:
For N = 5, the sequence is {5}, so length is 1
For N = 6, the sequence is {6, 5}, so length is 2
For N = 7, the sequence is {7}, so length is 1
For N = 8, the sequence is {8, 6, 5}, so length is 3
For N = 9, the sequence is {9, 6, 5}, so length is 3
For N = 10, the sequence is {10, 7}, so length is 2
Therefore, maximum length of sequence in this range is 3.Input: N = 2, M = 14
Output: 4
Naive Approach: The simplest approach to solve the problem is to iterate over the range [N, M], and for each integer, find its prime factors and sum them and repeat this for the sum obtained as well recursively until a sum which itself is a prime is obtained.
Efficient Approach: The above approach can be optimized using Dynamic Programming. Follow the steps below to solve the problem:
- Precompute the prime numbers using the Sieve of Eratosthenes method.
- Precompute the smallest prime factors of every integer to find out the prime factors, using Prime Factorization using Sieve.
- Now, for every integer in the range [N, M], calculate the sum of prime factors and repeat recursively for the obtained sum. Store the length of the sequence in the dp[] array, to avoid recomputation. If the sum obtained is a prime number, store further computation.
- Update the maximum length obtained and repeat the above step for every number in the range [N, M], except 4, which leads to infinite loop.
- Print the maximum length obtained.
Below is the implementation of the above approach:
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std;
// Smallest prime factor array int spf[100005];
// Stores if a number is prime or not bool prime[100005];
int dp[100005];
// Function to compute all primes // using Sieve of Eratosthenes void sieve()
{ prime[0] = prime[1] = false ;
for ( int i = 2; i < 100005; i++)
prime[i] = true ;
for ( int i = 2; i * i < 100005; i++) {
if (prime[i]) {
for ( int j = i * i; j < 100005; j += i) {
prime[j] = false ;
}
}
}
} // Function for finding smallest // prime factors for every integer void smallestPrimeFactors()
{ for ( int i = 0; i < 100005; i++)
spf[i] = -1;
for ( int i = 2; i * i < 100005; i++) {
for ( int j = i; j < 100005; j += i) {
if (spf[j] == -1) {
spf[j] = i;
}
}
}
} // Function to find the sum of // prime factors of number int sumOfPrimeFactors( int n)
{ int ans = 0;
while (n > 1) {
// Add smallest prime
// factor to the sum
ans += spf[n];
// Reduce N
n /= spf[n];
}
// Return the answer
return ans;
} // Function to return the length of // sequence of for the given number int findLength( int n)
{ // If the number is prime
if (prime[n]) {
return 1;
}
// If a previously computed
// subproblem occurred
if (dp[n]) {
return dp[n];
}
// Calculate the sum of
// prime factors
int sum = sumOfPrimeFactors(n);
return dp[n] = 1 + findLength(sum);
} // Function to return the maximum length // of sequence for the given range int maxLength( int n, int m)
{ // Pre-calculate primes
sieve();
// Precalculate smallest
// prime factors
smallestPrimeFactors();
int ans = INT_MIN;
// Iterate over the range
for ( int i = n; i <= m; i++) {
if (i == 4) {
continue ;
}
// Update maximum length
ans = max(ans, findLength(i));
}
return ans;
} // Driver Code int main()
{ int n = 2, m = 14;
cout << maxLength(n, m);
} |
// Java Program to implement // the above approach import java.util.*;
class GFG{
// Smallest prime factor array static int spf[] = new int [ 100005 ];
// Stores if a number is prime or not static boolean prime[] = new boolean [ 100005 ];
static int dp[] = new int [ 100005 ];
// Function to compute all primes // using Sieve of Eratosthenes static void sieve()
{ prime[ 0 ] = prime[ 1 ] = false ;
for ( int i = 2 ; i < 100005 ; i++)
prime[i] = true ;
for ( int i = 2 ; i * i < 100005 ; i++)
{
if (prime[i])
{
for ( int j = i * i; j < 100005 ; j += i)
{
prime[j] = false ;
}
}
}
} // Function for finding smallest // prime factors for every integer static void smallestPrimeFactors()
{ for ( int i = 0 ; i < 100005 ; i++)
spf[i] = - 1 ;
for ( int i = 2 ; i * i < 100005 ; i++)
{
for ( int j = i; j < 100005 ; j += i)
{
if (spf[j] == - 1 )
{
spf[j] = i;
}
}
}
} // Function to find the sum of // prime factors of number static int sumOfPrimeFactors( int n)
{ int ans = 0 ;
while (n > 1 )
{
// Add smallest prime
// factor to the sum
ans += spf[n];
// Reduce N
n /= spf[n];
}
// Return the answer
return ans;
} // Function to return the length of // sequence of for the given number static int findLength( int n)
{ // If the number is prime
if (prime[n])
{
return 1 ;
}
// If a previously computed
// subproblem occurred
if (dp[n] != 0 )
{
return dp[n];
}
// Calculate the sum of
// prime factors
int sum = sumOfPrimeFactors(n);
return dp[n] = 1 + findLength(sum);
} // Function to return the maximum length // of sequence for the given range static int maxLength( int n, int m)
{ // Pre-calculate primes
sieve();
// Precalculate smallest
// prime factors
smallestPrimeFactors();
int ans = Integer.MIN_VALUE;
// Iterate over the range
for ( int i = n; i <= m; i++)
{
if (i == 4 )
{
continue ;
}
// Update maximum length
ans = Math.max(ans, findLength(i));
}
return ans;
} // Driver Code public static void main(String[] args)
{ int n = 2 , m = 14 ;
System.out.print(maxLength(n, m));
} } // This code is contributed by Princi Singh |
# Python3 program to implement # the above approach import sys
# Smallest prime factor array spf = [ 0 ] * 100005
# Stores if a number is prime or not prime = [ False ] * 100005
dp = [ 0 ] * 100005
# Function to compute all primes # using Sieve of Eratosthenes def sieve():
for i in range ( 2 , 100005 ):
prime[i] = True
i = 2
while i * i < 100005 :
if (prime[i]):
for j in range (i * i, 100005 , i):
prime[j] = False
i + = 1
# Function for finding smallest # prime factors for every integer def smallestPrimeFactors():
for i in range ( 10005 ):
spf[i] = - 1
i = 2
while i * i < 100005 :
for j in range (i, 100005 , i):
if (spf[j] = = - 1 ):
spf[j] = i
i + = 1
# Function to find the sum of # prime factors of number def sumOfPrimeFactors(n):
ans = 0
while (n > 1 ):
# Add smallest prime
# factor to the sum
ans + = spf[n]
# Reduce N
n / / = spf[n]
# Return the answer
return ans
# Function to return the length of # sequence of for the given number def findLength(n):
# If the number is prime
if (prime[n]):
return 1
# If a previously computed
# subproblem occurred
if (dp[n]):
return dp[n]
# Calculate the sum of
# prime factors
sum = sumOfPrimeFactors(n)
dp[n] = 1 + findLength( sum )
return dp[n]
# Function to return the maximum length # of sequence for the given range def maxLength(n, m):
# Pre-calculate primes
sieve()
# Precalculate smallest
# prime factors
smallestPrimeFactors()
ans = - sys.maxsize - 1
# Iterate over the range
for i in range (n, m + 1 ):
if (i = = 4 ):
continue
# Update maximum length
ans = max (ans, findLength(i))
return ans
# Driver Code n = 2
m = 14
# Function call print (maxLength(n, m))
# This code is contributed by Shivam Singh |
// C# program to implement // the above approach using System;
class GFG{
// Smallest prime factor array static int []spf = new int [100005];
// Stores if a number is prime or not static bool []prime = new bool [100005];
static int []dp = new int [100005];
// Function to compute all primes // using Sieve of Eratosthenes static void sieve()
{ prime[0] = prime[1] = false ;
for ( int i = 2; i < 100005; i++)
prime[i] = true ;
for ( int i = 2; i * i < 100005; i++)
{
if (prime[i])
{
for ( int j = i * i; j < 100005; j += i)
{
prime[j] = false ;
}
}
}
} // Function for finding smallest // prime factors for every integer static void smallestPrimeFactors()
{ for ( int i = 0; i < 100005; i++)
spf[i] = -1;
for ( int i = 2; i * i < 100005; i++)
{
for ( int j = i; j < 100005; j += i)
{
if (spf[j] == -1)
{
spf[j] = i;
}
}
}
} // Function to find the sum of // prime factors of number static int sumOfPrimeFactors( int n)
{ int ans = 0;
while (n > 1)
{
// Add smallest prime
// factor to the sum
ans += spf[n];
// Reduce N
n /= spf[n];
}
// Return the answer
return ans;
} // Function to return the length of // sequence of for the given number static int findLength( int n)
{ // If the number is prime
if (prime[n])
{
return 1;
}
// If a previously computed
// subproblem occurred
if (dp[n] != 0)
{
return dp[n];
}
// Calculate the sum of
// prime factors
int sum = sumOfPrimeFactors(n);
return dp[n] = 1 + findLength(sum);
} // Function to return the maximum length // of sequence for the given range static int maxLength( int n, int m)
{ // Pre-calculate primes
sieve();
// Precalculate smallest
// prime factors
smallestPrimeFactors();
int ans = int .MinValue;
// Iterate over the range
for ( int i = n; i <= m; i++)
{
if (i == 4)
{
continue ;
}
// Update maximum length
ans = Math.Max(ans, findLength(i));
}
return ans;
} // Driver Code public static void Main(String[] args)
{ int n = 2, m = 14;
Console.Write(maxLength(n, m));
} } // This code is contributed by 29AjayKumar |
<script> // JavaScript program to implement // the above approach // Smallest prime factor array let spf = Array.from({length: 100005}, (_, i) => 0); // Stores if a number is prime or not let prime = Array.from({length: 100005}, (_, i) => 0); let dp = Array.from({length: 100005}, (_, i) => 0); // Function to compute all primes // using Sieve of Eratosthenes function sieve()
{ prime[0] = prime[1] = false ;
for (let i = 2; i < 100005; i++)
prime[i] = true ;
for (let i = 2; i * i < 100005; i++)
{
if (prime[i])
{
for (let j = i * i; j < 100005; j += i)
{
prime[j] = false ;
}
}
}
} // Function for finding smallest // prime factors for every integer function smallestPrimeFactors()
{ for (let i = 0; i < 100005; i++)
spf[i] = -1;
for (let i = 2; i * i < 100005; i++)
{
for (let j = i; j < 100005; j += i)
{
if (spf[j] == -1)
{
spf[j] = i;
}
}
}
} // Function to find the sum of // prime factors of number function sumOfPrimeFactors(n)
{ let ans = 0;
while (n > 1)
{
// Add smallest prime
// factor to the sum
ans += spf[n];
// Reduce N
n /= spf[n];
}
// Return the answer
return ans;
} // Function to return the length of // sequence of for the given number function findLength(n)
{ // If the number is prime
if (prime[n])
{
return 1;
}
// If a previously computed
// subproblem occurred
if (dp[n] != 0)
{
return dp[n];
}
// Calculate the sum of
// prime factors
let sum = sumOfPrimeFactors(n);
return dp[n] = 1 + findLength(sum);
} // Function to return the maximum length // of sequence for the given range function maxLength(n, m)
{ // Pre-calculate primes
sieve();
// Precalculate smallest
// prime factors
smallestPrimeFactors();
let ans = Number.MIN_VALUE;
// Iterate over the range
for (let i = n; i <= m; i++)
{
if (i == 4)
{
continue ;
}
// Update maximum length
ans = Math.max(ans, findLength(i));
}
return ans;
} // Driver Code let n = 2, m = 14;
document.write(maxLength(n, m));
</script> |
4
Time complexity: O((NlogN)
Auxiliary Space: O(N)