Skip to content
Related Articles
Open in App
Not now

Related Articles

Maximum sum of values in a given range of an Array for Q queries when shuffling is allowed

Improve Article
Save Article
Like Article
  • Last Updated : 19 Apr, 2021
Improve Article
Save Article
Like Article

Given an array arr[] and K subarrays in the form (Li, Ri), the task is to find the maximum possible value of 

\sum_{i = 1}^{K} arr[L_i:R_i]
 

. It is allowed to shuffle the array before calculating this value to get the maximum sum.

Examples: 

Input: arr[] = {1, 1, 2, 2, 4}, queries = {{1, 2}, {2, 4}, {1, 3}, {5, 5}, {3, 5}} 
Output: 26 
Explanation: 
Shuffled Array to get the maximum sum – {2, 4, 2, 1, 1} 
Subarray Sum = arr[1:2] + arr[2:4] + arr[1:3] + arr[5:5] + arr[3:5] 
=> 6 + 7 + 8 + 1 + 4 = 26

Input: arr[] = {4, 1, 2, 1, 9, 2}, queries = {{1, 2}, {1, 3}, {1, 4}, {3, 4}} 
Output: 49 
Explanation: 
Shuffled Array to get the maximum sum – {2, 4, 9, 2, 1, 1} 
Subarray Sum = arr[1:2] + arr[1:3] + arr[1:4] + arr[3:4] 
=> 6 + 15 + 17 + 11 = 49 

Naive Approach: A simple solution is to compute the maximum sum of all possible permutations of the given array and check which sequence gives us the maximum summation.

Efficient Approach: The idea is to use Prefix Arrays to find out the frequency of indices over all subarrays. We can do this as follows:  

//Initialize an array 
prefSum[n] = {0, 0, ...0}
for each Li, Ri:
    prefSum[Li]++
    prefSum[Ri+1]--

// Find Prefix sum
for i=1 to N:
    prefSum[i] += prefSum[i-1]

// prefSum contains frequency of 
// each index over all subarrays

Finally, greedily choose the index with the highest frequency and put the largest element of the array at that index. This way we will get the largest possible sum.

Below is the implementation of the above approach: 

C++




// C++ implementation to find the
// maximum sum of K subarrays
// when shuffling is allowed
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the
// maximum sum of all subarrays
int maximumSubarraySum(
    int a[], int n,
    vector<pair<int, int> >& subarrays)
{
    // Initialize maxsum
    // and prefixArray
    int i, maxsum = 0;
    int prefixArray[n] = { 0 };
 
    // Find the frequency
    // using prefix Array
    for (i = 0; i < subarrays.size(); ++i) {
        prefixArray[subarrays[i].first - 1]++;
        prefixArray[subarrays[i].second]--;
    }
 
    // Perform prefix sum
    for (i = 1; i < n; i++) {
        prefixArray[i] += prefixArray[i - 1];
    }
 
    // Sort both arrays to get a greedy result
    sort(prefixArray,
        prefixArray + n,
        greater<int>());
    sort(a, a + n, greater<int>());
 
    // Finally multiply largest frequency with
    // largest array element.
    for (i = 0; i < n; i++)
        maxsum += a[i] * prefixArray[i];
 
    // Return the answer
    return maxsum;
}
 
// Driver Code
int main()
{
    int n = 6;
 
    // Initial Array
    int a[] = { 4, 1, 2, 1, 9, 2 };
 
    // Subarrays
    vector<pair<int, int> > subarrays;
    subarrays.push_back({ 1, 2 });
    subarrays.push_back({ 1, 3 });
    subarrays.push_back({ 1, 4 });
    subarrays.push_back({ 3, 4 });
 
    // Function Call
    cout << maximumSubarraySum(a, n,
                            subarrays);
}


Java




// Java implementation to find the
// maximum sum of K subarrays
// when shuffling is allowed
import java.util.*;
import java.lang.*;
 
class GFG{
     
// Function to find the
// maximum sum of all subarrays
static int maximumSubarraySum(int a[], int n,
           ArrayList<List<Integer>> subarrays)
{
     
    // Initialize maxsum
    // and prefixArray
    int i, maxsum = 0;
    int[] prefixArray = new int[n];
  
    // Find the frequency
    // using prefix Array
    for(i = 0; i < subarrays.size(); ++i)
    {
        prefixArray[subarrays.get(i).get(0) - 1]++;
        prefixArray[subarrays.get(i).get(1)]--;
    }
  
    // Perform prefix sum
    for(i = 1; i < n; i++)
    {
        prefixArray[i] += prefixArray[i - 1];
    }
  
    // Sort both arrays to get a
    // greedy result
    Arrays.sort(prefixArray);
    Arrays.sort(a);
  
    // Finally multiply largest
    // frequency with largest
    // array element.
    for(i = 0; i < n; i++)
        maxsum += a[i] * prefixArray[i];
         
    // Return the answer
    return maxsum;
}
  
// Driver code
public static void main (String[] args)
{
    int n = 6;
     
    // Initial Array
    int a[] = { 4, 1, 2, 1, 9, 2 };
     
    // Subarrays
    ArrayList<List<Integer>> subarrays = new ArrayList<>();
    subarrays.add(Arrays.asList(1, 2));
    subarrays.add(Arrays.asList(1, 3));
    subarrays.add(Arrays.asList(1, 4));
    subarrays.add(Arrays.asList(3, 4));
     
    // Function call
    System.out.println(maximumSubarraySum(a, n,
                                          subarrays));
}
}
 
// This code is contributed by offbeat


Python3




# Python3 implementation to find the
# maximum sum of K subarrays
# when shuffling is allowed
 
# Function to find the
# maximum sum of all subarrays
def maximumSubarraySum(a, n, subarrays):
 
    # Initialize maxsum
    # and prefixArray
    maxsum = 0
    prefixArray = [0] * n
 
    # Find the frequency
    # using prefix Array
    for i in range(len(subarrays)):
        prefixArray[subarrays[i][0] - 1] += 1
        prefixArray[subarrays[i][1]] -= 1
 
    # Perform prefix sum
    for i in range(1, n):
        prefixArray[i] += prefixArray[i - 1]
 
    # Sort both arrays to get a greedy result
    prefixArray.sort()
    prefixArray.reverse()
    a.sort()
    a.reverse()
 
    # Finally multiply largest frequency with
    # largest array element.
    for i in range(n):
        maxsum += a[i] * prefixArray[i]
 
    # Return the answer
    return maxsum
 
# Driver Code
n = 6
 
# Initial Array
a = [ 4, 1, 2, 1, 9, 2 ]
 
# Subarrays
subarrays = [ [ 1, 2 ], [ 1, 3 ],
              [ 1, 4 ], [ 3, 4 ] ]
 
# Function Call
print(maximumSubarraySum(a, n, subarrays))
 
# This code is contributed by divyeshrabadiya07


C#




// C# implementation to find the
// maximum sum of K subarrays
// when shuffling is allowed
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to find the
// maximum sum of all subarrays
static int maximumSubarraySum(int[] a, int n,
                    List<List<int>> subarrays)
{
     
    // Initialize maxsum
    // and prefixArray
    int i, maxsum = 0;
    int[] prefixArray = new int[n];
   
    // Find the frequency
    // using prefix Array
    for(i = 0; i < subarrays.Count; ++i)
    {
        prefixArray[subarrays[i][0] - 1]++;
        prefixArray[subarrays[i][1]]--;
    }
   
    // Perform prefix sum
    for(i = 1; i < n; i++)
    {
        prefixArray[i] += prefixArray[i - 1];
    }
   
    // Sort both arrays to get a
    // greedy result
    Array.Sort(prefixArray);
    Array.Sort(a);
   
    // Finally multiply largest
    // frequency with largest
    // array element.
    for(i = 0; i < n; i++)
        maxsum += a[i] * prefixArray[i];
          
    // Return the answer
    return maxsum;
}
 
// Driver Code
static void Main()
{
    int n = 6;
     
    // Initial Array
    int[] a = { 4, 1, 2, 1, 9, 2 };
      
    // Subarrays
    List<List<int>> subarrays = new List<List<int>>();
    subarrays.Add(new List<int>{ 1, 2 });
    subarrays.Add(new List<int>{ 1, 3 });
    subarrays.Add(new List<int>{ 1, 4 });
    subarrays.Add(new List<int>{ 3, 4 });
      
    // Function call
    Console.WriteLine(maximumSubarraySum(a, n,subarrays));
}
}
 
// This code is contributed by divyesh072019


Javascript




<script>
 
    // Javascript implementation to find the
    // maximum sum of K subarrays
    // when shuffling is allowed
     
    // Function to find the
    // maximum sum of all subarrays
    function maximumSubarraySum(a, n, subarrays)
    {
 
        // Initialize maxsum
        // and prefixArray
        let i, maxsum = 0;
        let prefixArray = new Array(n);
        prefixArray.fill(0);
 
        // Find the frequency
        // using prefix Array
        for(i = 0; i < subarrays.length; ++i)
        {
            prefixArray[subarrays[i][0] - 1]++;
            prefixArray[subarrays[i][1]]--;
        }
 
        // Perform prefix sum
        for(i = 1; i < n; i++)
        {
            prefixArray[i] += prefixArray[i - 1];
        }
 
        // Sort both arrays to get a
        // greedy result
        prefixArray.sort();
        a.sort();
 
        // Finally multiply largest
        // frequency with largest
        // array element.
        for(i = 0; i < n; i++)
            maxsum += a[i] * prefixArray[i];
 
        // Return the answer
        return maxsum;
    }
     
    let n = 6;
      
    // Initial Array
    let a = [ 4, 1, 2, 1, 9, 2 ];
       
    // Subarrays
    let subarrays = [];
    subarrays.push([ 1, 2 ]);
    subarrays.push([ 1, 3 ]);
    subarrays.push([ 1, 4 ]);
    subarrays.push([ 3, 4 ]);
       
    // Function call
    document.write(maximumSubarraySum(a, n,subarrays));
 
</script>


Output: 

49

 

 


My Personal Notes arrow_drop_up
Like Article
Save Article
Related Articles

Start Your Coding Journey Now!