Maximum Length of Sequence of Sums of prime factors generated by the given operations
Last Updated :
14 Sep, 2021
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++
#include <bits/stdc++.h>
using namespace std;
int spf[100005];
bool prime[100005];
int dp[100005];
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 ;
}
}
}
}
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;
}
}
}
}
int sumOfPrimeFactors( int n)
{
int ans = 0;
while (n > 1) {
ans += spf[n];
n /= spf[n];
}
return ans;
}
int findLength( int n)
{
if (prime[n]) {
return 1;
}
if (dp[n]) {
return dp[n];
}
int sum = sumOfPrimeFactors(n);
return dp[n] = 1 + findLength(sum);
}
int maxLength( int n, int m)
{
sieve();
smallestPrimeFactors();
int ans = INT_MIN;
for ( int i = n; i <= m; i++) {
if (i == 4) {
continue ;
}
ans = max(ans, findLength(i));
}
return ans;
}
int main()
{
int n = 2, m = 14;
cout << maxLength(n, m);
}
|
Java
import java.util.*;
class GFG{
static int spf[] = new int [ 100005 ];
static boolean prime[] = new boolean [ 100005 ];
static int dp[] = new int [ 100005 ];
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 ;
}
}
}
}
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;
}
}
}
}
static int sumOfPrimeFactors( int n)
{
int ans = 0 ;
while (n > 1 )
{
ans += spf[n];
n /= spf[n];
}
return ans;
}
static int findLength( int n)
{
if (prime[n])
{
return 1 ;
}
if (dp[n] != 0 )
{
return dp[n];
}
int sum = sumOfPrimeFactors(n);
return dp[n] = 1 + findLength(sum);
}
static int maxLength( int n, int m)
{
sieve();
smallestPrimeFactors();
int ans = Integer.MIN_VALUE;
for ( int i = n; i <= m; i++)
{
if (i == 4 )
{
continue ;
}
ans = Math.max(ans, findLength(i));
}
return ans;
}
public static void main(String[] args)
{
int n = 2 , m = 14 ;
System.out.print(maxLength(n, m));
}
}
|
Python3
import sys
spf = [ 0 ] * 100005
prime = [ False ] * 100005
dp = [ 0 ] * 100005
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
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
def sumOfPrimeFactors(n):
ans = 0
while (n > 1 ):
ans + = spf[n]
n / / = spf[n]
return ans
def findLength(n):
if (prime[n]):
return 1
if (dp[n]):
return dp[n]
sum = sumOfPrimeFactors(n)
dp[n] = 1 + findLength( sum )
return dp[n]
def maxLength(n, m):
sieve()
smallestPrimeFactors()
ans = - sys.maxsize - 1
for i in range (n, m + 1 ):
if (i = = 4 ):
continue
ans = max (ans, findLength(i))
return ans
n = 2
m = 14
print (maxLength(n, m))
|
C#
using System;
class GFG{
static int []spf = new int [100005];
static bool []prime = new bool [100005];
static int []dp = new int [100005];
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 ;
}
}
}
}
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;
}
}
}
}
static int sumOfPrimeFactors( int n)
{
int ans = 0;
while (n > 1)
{
ans += spf[n];
n /= spf[n];
}
return ans;
}
static int findLength( int n)
{
if (prime[n])
{
return 1;
}
if (dp[n] != 0)
{
return dp[n];
}
int sum = sumOfPrimeFactors(n);
return dp[n] = 1 + findLength(sum);
}
static int maxLength( int n, int m)
{
sieve();
smallestPrimeFactors();
int ans = int .MinValue;
for ( int i = n; i <= m; i++)
{
if (i == 4)
{
continue ;
}
ans = Math.Max(ans, findLength(i));
}
return ans;
}
public static void Main(String[] args)
{
int n = 2, m = 14;
Console.Write(maxLength(n, m));
}
}
|
Javascript
<script>
let spf = Array.from({length: 100005}, (_, i) => 0);
let prime = Array.from({length: 100005}, (_, i) => 0);
let dp = Array.from({length: 100005}, (_, i) => 0);
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 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 sumOfPrimeFactors(n)
{
let ans = 0;
while (n > 1)
{
ans += spf[n];
n /= spf[n];
}
return ans;
}
function findLength(n)
{
if (prime[n])
{
return 1;
}
if (dp[n] != 0)
{
return dp[n];
}
let sum = sumOfPrimeFactors(n);
return dp[n] = 1 + findLength(sum);
}
function maxLength(n, m)
{
sieve();
smallestPrimeFactors();
let ans = Number.MIN_VALUE;
for (let i = n; i <= m; i++)
{
if (i == 4)
{
continue ;
}
ans = Math.max(ans, findLength(i));
}
return ans;
}
let n = 2, m = 14;
document.write(maxLength(n, m));
</script>
|
Time complexity: O((NlogN)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...