Open In App

Maximum sum of K-length subarray with maximum count of distinct prime factors

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] consisting of N positive integers and an integer K, the task is to find the maximum sum of array elements in a subarray having maximum sum of distinct prime factors in each K-length subarray. 
Note: If there are multiple answers then print the sum of the original subarray having maximum sum.

Examples:

Input: arr[] = {1, 4, 2, 10, 3}, K = 3
Output: 16
Explanation: 
All possible subarrays of length 3 are:
{1, 4, 2} ? having 0+1+1= 2 distinct prime factors
{4, 2, 10} ? having 1+1+2= 4 distinct prime factors. Sum = 16.
{2, 10, 3} ? having 1+1+2= 4 distinct prime factors. Sum = 15.
Therefore, maximum sum of K length subarrays with maximum distinct prime factors is 16.

Input: arr[] = {10, 14, 12, 9, 16, 11}, K = 2
Output: 26

Naive Approach: The simplest approach is to generate all possible subarrays of length K from the given array and traverse each subarray and count distinct prime factors of its elements and compute their sums. Finally, print the maximum sum among subarrays having maximum count of distinct prime factors.
Time Complexity: O(N3 * sqrt(MAX)), where MAX is the maximum number present in the array.
Auxiliary Space: O(N * sqrt(MAX))

Efficient Approach: The optimal idea is to use Sieve of Eratosthenes and Sliding window technique to solve this problem. Follow the steps below to solve the problem:

  • Initialize an array, say CountDsitinct[], to store the count of distinct prime factors up to a limit using sieve by incrementing the count of CountDistinct[] every time, while marking multiples of prime number as false.
  • The sum of a subarray (or window) of size K can be obtained in constant time using the sum of the previous subarray (or window) of size K using  Sliding window technique.
  • Traverse the array arr[] and check which subarray has the maximum sum of distinct prime numbers. 
  • Finally, print the sum of the subarray or the sum of the original array having the maximum count of prime factors.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
#define MAX 100001
 
// Function to print the sum of
// subarray of length K having
// maximum distinct prime factors
int maxSum(int arr[], int N, int K)
{
    // If K exceeds N
    if (N < K) {
        cout << "Invalid";
        return -1;
    }
 
    // Stores the count of distinct primes
    int CountDistinct[MAX + 1];
 
    // True, if index 'i' is a prime
    bool prime[MAX + 1];
 
    // Initialize the count of factors
    // to 0 and set all indices as prime
    for (int i = 0; i <= MAX; i++) {
        CountDistinct[i] = 0;
        prime[i] = true;
    }
 
    for (long long int i = 2; i <= MAX; i++) {
 
        // If i is prime
        if (prime[i] == true) {
 
            // Number is prime
            CountDistinct[i] = 1;
 
            // Count of factors of a prime number is 1
            for (long long int j = i * 2; j <= MAX;
                 j += i) {
 
                // Increment CountDistinct as
                // the factors of i
                CountDistinct[j]++;
 
                // Mark its multiple non-prime
                prime[j] = false;
            }
        }
    }
 
    // Compute sum of first K-length subarray
    int Maxarr_sum = 0, DistPrimeSum = 0;
    for (int i = 0; i < K; i++) {
       
        Maxarr_sum += arr[i];
        DistPrimeSum += CountDistinct[arr[i]];
    }
 
    // Compute sums of remaining windows
    // by removing first element of the
    // previous window and adding last
    // element of the current window
    int curr_sum = DistPrimeSum;
    int curr_arrSum = Maxarr_sum;
 
    for (int i = K; i < N; i++) {
       
        curr_sum += CountDistinct[arr[i]]
                    - CountDistinct[arr[i - K]];
       
        curr_arrSum += arr[i] - arr[i - K];
        if (curr_sum > DistPrimeSum) {
           
            DistPrimeSum = curr_sum;
            Maxarr_sum = curr_arrSum;
        }
        else if (curr_sum == DistPrimeSum) {
           
            Maxarr_sum = max(
              curr_arrSum, Maxarr_sum);
        }
    }
 
    // Print the maximum sum
    cout << Maxarr_sum;
}
 
// Driver Code
int main()
{
    // Given array
    int arr[] = { 1, 4, 2, 10, 3 };
 
    // Given  size of subarray
    int K = 3;
 
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    maxSum(arr, N, K);
 
    return 0;
}


Java




// Java Program to implement
// the above approach
import java.io.*;
import java.util.*;
 
class GFG
{
 
  static int MAX = 100001;
 
  // Function to print the sum of
  // subarray of length K having
  // maximum distinct prime factors
  static void maxSum(int arr[], int N, int K)
  {
 
    // If K exceeds N
    if (N < K) {
      System.out.println("Invalid");
      return;
    }
 
    // Stores the count of distinct primes
    int CountDistinct[] = new int[MAX + 1];
 
    // True, if index 'i' is a prime
    boolean prime[] = new boolean[MAX + 1];
 
    // Initialize the count of factors
    // to 0 and set all indices as prime
    for (int i = 0; i <= MAX; i++) {
      CountDistinct[i] = 0;
      prime[i] = true;
    }
 
    for (int i = 2; i <= MAX; i++) {
 
      // If i is prime
      if (prime[i] == true) {
 
        // Number is prime
        CountDistinct[i] = 1;
 
        // Count of factors of a prime number is 1
        for (int j = i * 2; j <= MAX; j += i) {
 
          // Increment CountDistinct as
          // the factors of i
          CountDistinct[j]++;
 
          // Mark its multiple non-prime
          prime[j] = false;
        }
      }
    }
 
    // Compute sum of first K-length subarray
    int Maxarr_sum = 0, DistPrimeSum = 0;
    for (int i = 0; i < K; i++) {
 
      Maxarr_sum += arr[i];
      DistPrimeSum += CountDistinct[arr[i]];
    }
 
    // Compute sums of remaining windows
    // by removing first element of the
    // previous window and adding last
    // element of the current window
    int curr_sum = DistPrimeSum;
    int curr_arrSum = Maxarr_sum;
 
    for (int i = K; i < N; i++) {
 
      curr_sum += CountDistinct[arr[i]]
        - CountDistinct[arr[i - K]];
 
      curr_arrSum += arr[i] - arr[i - K];
      if (curr_sum > DistPrimeSum) {
 
        DistPrimeSum = curr_sum;
        Maxarr_sum = curr_arrSum;
      }
      else if (curr_sum == DistPrimeSum) {
 
        Maxarr_sum
          = Math.max(curr_arrSum, Maxarr_sum);
      }
    }
 
    // Print the maximum sum
    System.out.println(Maxarr_sum);
  }
 
  // Driver Code
  public static void main(String[] args)
  {
 
    // Given array
    int arr[] = { 1, 4, 2, 10, 3 };
 
    // Given  size of subarray
    int K = 3;
 
    // Size of the array
    int N = arr.length;
 
    maxSum(arr, N, K);
  }
}
 
// This code is contributed by Kingash.


Python3




# Python3 program for the above approach
import math
 
MAX = 100001
 
# Function to print the sum of
# subarray of length K having
# maximum distinct prime factors
def maxSum(arr, N, K):
   
    # If K exceeds N
    if (N < K):
        print("Invalid")
        return -1
 
    # Stores the count of distinct primes
    CountDistinct = [0]*(MAX + 1)
 
    # True, if index 'i' is a prime
    prime = [0]*(MAX + 1)
 
    # Initialize the count of factors
    # to 0 and set all indices as prime
    for i in range(0,MAX+1):
        CountDistinct[i] = 0
        prime[i] = True
 
    for i in range(2,MAX+1):
 
        # If i is prime
        if (prime[i] == True):
 
            # Number is prime
            CountDistinct[i] = 1
 
            # Count of factors of a prime number is 1
            for j in range(i * 2,MAX+1,i):
 
                # Increment CountDistinct as
                # the factors of i
                CountDistinct[j] += 1
 
                # Mark its multiple non-prime
                prime[j] = False
 
    # Compute sum of first K-length subarray
    Maxarr_sum,DistPrimeSum = 0,0
    for i in range(0,K):
     
        Maxarr_sum += arr[i]
        DistPrimeSum += CountDistinct[arr[i]]
 
    # Compute sums of remaining windows
    # by removing first element of the
    # previous window and adding last
    # element of the current window
    curr_sum = DistPrimeSum
    curr_arrSum = Maxarr_sum
 
    for i in range(K,N):
     
        curr_sum += CountDistinct[arr[i]]- CountDistinct[arr[i - K]]
     
        curr_arrSum += arr[i] - arr[i - K]
        if (curr_sum > DistPrimeSum):
         
            DistPrimeSum = curr_sum
            Maxarr_sum = curr_arrSum
 
        elif (curr_sum == DistPrimeSum):
         
            Maxarr_sum = max(curr_arrSum, Maxarr_sum)
 
    print(Maxarr_sum)
 
# Driver Code
 
# Given array
arr = [ 1, 4, 2, 10, 3 ]
 
# Given size of subarray
K = 3
 
# Size of the array
N = len(arr)
maxSum(arr, N, K)
 
# This code is contributed by shinjanpatra


C#




// C# Program to implement
// the above approach
using System;
public class GFG
{
 
  static int MAX = 100001;
 
  // Function to print the sum of
  // subarray of length K having
  // maximum distinct prime factors
  static void maxSum(int []arr, int N, int K)
  {
 
    // If K exceeds N
    if (N < K) {
      Console.WriteLine("Invalid");
      return;
    }
 
    // Stores the count of distinct primes
    int []CountDistinct = new int[MAX + 1];
 
    // True, if index 'i' is a prime
    bool []prime = new bool[MAX + 1];
 
    // Initialize the count of factors
    // to 0 and set all indices as prime
    for (int i = 0; i <= MAX; i++) {
      CountDistinct[i] = 0;
      prime[i] = true;
    }
 
    for (int i = 2; i <= MAX; i++) {
 
      // If i is prime
      if (prime[i] == true) {
 
        // Number is prime
        CountDistinct[i] = 1;
 
        // Count of factors of a prime number is 1
        for (int j = i * 2; j <= MAX; j += i) {
 
          // Increment CountDistinct as
          // the factors of i
          CountDistinct[j]++;
 
          // Mark its multiple non-prime
          prime[j] = false;
        }
      }
    }
 
    // Compute sum of first K-length subarray
    int Maxarr_sum = 0, DistPrimeSum = 0;
    for (int i = 0; i < K; i++) {
 
      Maxarr_sum += arr[i];
      DistPrimeSum += CountDistinct[arr[i]];
    }
 
    // Compute sums of remaining windows
    // by removing first element of the
    // previous window and adding last
    // element of the current window
    int curr_sum = DistPrimeSum;
    int curr_arrSum = Maxarr_sum;
 
    for (int i = K; i < N; i++) {
 
      curr_sum += CountDistinct[arr[i]]
        - CountDistinct[arr[i - K]];
 
      curr_arrSum += arr[i] - arr[i - K];
      if (curr_sum > DistPrimeSum) {
 
        DistPrimeSum = curr_sum;
        Maxarr_sum = curr_arrSum;
      }
      else if (curr_sum == DistPrimeSum) {
 
        Maxarr_sum
          = Math.Max(curr_arrSum, Maxarr_sum);
      }
    }
 
    // Print the maximum sum
    Console.WriteLine(Maxarr_sum);
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
 
    // Given array
    int []arr = { 1, 4, 2, 10, 3 };
 
    // Given  size of subarray
    int K = 3;
 
    // Size of the array
    int N = arr.Length;
 
    maxSum(arr, N, K);
  }
}
 
// This code is contributed by 29AjayKumar


Javascript




<script>
 
// Javascript program for the above approach
 
 
let MAX = 100001
 
// Function to print the sum of
// subarray of length K having
// maximum distinct prime factors
function maxSum(arr, N, K)
{
    // If K exceeds N
    if (N < K) {
        document.write("Invalid");
        return -1;
    }
 
    // Stores the count of distinct primes
    let CountDistinct = new Array(MAX + 1);
 
    // True, if index 'i' is a prime
    let prime = new Array(MAX + 1);
 
    // Initialize the count of factors
    // to 0 and set all indices as prime
    for (let i = 0; i <= MAX; i++) {
        CountDistinct[i] = 0;
        prime[i] = true;
    }
 
    for (let i = 2; i <= MAX; i++) {
 
        // If i is prime
        if (prime[i] == true) {
 
            // Number is prime
            CountDistinct[i] = 1;
 
            // Count of factors of a prime number is 1
            for (let j = i * 2; j <= MAX;
                j += i) {
 
                // Increment CountDistinct as
                // the factors of i
                CountDistinct[j]++;
 
                // Mark its multiple non-prime
                prime[j] = false;
            }
        }
    }
 
    // Compute sum of first K-length subarray
    let Maxarr_sum = 0, DistPrimeSum = 0;
    for (let i = 0; i < K; i++) {
     
        Maxarr_sum += arr[i];
        DistPrimeSum += CountDistinct[arr[i]];
    }
 
    // Compute sums of remaining windows
    // by removing first element of the
    // previous window and adding last
    // element of the current window
    let curr_sum = DistPrimeSum;
    let curr_arrSum = Maxarr_sum;
 
    for (let i = K; i < N; i++) {
     
        curr_sum += CountDistinct[arr[i]]
                    - CountDistinct[arr[i - K]];
     
        curr_arrSum += arr[i] - arr[i - K];
        if (curr_sum > DistPrimeSum) {
         
            DistPrimeSum = curr_sum;
            Maxarr_sum = curr_arrSum;
        }
        else if (curr_sum == DistPrimeSum) {
         
            Maxarr_sum = Math.max(curr_arrSum, Maxarr_sum);
        }
    }
 
    // Print the maximum sum
    document.write(Maxarr_sum);
}
 
// Driver Code
 
// Given array
let arr = [ 1, 4, 2, 10, 3 ];
 
// Given size of subarray
let K = 3;
 
// Size of the array
let N = arr.length
maxSum(arr, N, K);
 
</script>


 
 

Output

16

 

Time Complexity: O(N * log N)
Auxiliary Space: O(N)

 



Last Updated : 10 Mar, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads