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:
- 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> |
4
Time complexity: O((NlogN)
Auxiliary Space: O(N)
Please Login to comment...