Skip to content
Related Articles
Get the best out of our app
GeeksforGeeks App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Maximum Length of Sequence of Sums of prime factors generated by the given operations

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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++




// 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




// 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




# 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#




// 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

Javascript




<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>

Output: 

4

Time complexity: O((NlogN) 
Auxiliary Space: O(N)


My Personal Notes arrow_drop_up
Last Updated : 14 Sep, 2021
Like Article
Save Article
Similar Reads
Related Tutorials