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

Given two integers N and M, the task is to perform the following operations:

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:



Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 smllest
    // 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);
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

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

filter_none

edit
close

play_arrow

link
brightness_4
code

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

filter_none

edit
close

play_arrow

link
brightness_4
code

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

Output: 
4

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




Recommended Posts:


Check out this Author's contributed articles.

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 Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Article Tags :