# Sum of maximum of all subarrays by adding even frequent maximum twice

• Last Updated : 30 Jun, 2021

Given an array arr[] consisting of N integers (All array elements are a perfect power of 2), the task is to calculate the sum of the maximum elements in all the subarrays

Note: If the frequency of the maximum element in a subarray is even, add twice the value of that element to the sum.

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Examples:

Input: arr[] = {1, 2}
Output: 5
Explanation: All possible subarrays are {1}, {1, 2}, {2}.
Subarray 1: {1}. Maximum = 1. Sum = 1.
Subarray 2: {1, 2}. Maximum = 2. Sum = 3.
Subarray 3: {2}. Maximum = 2.Sum = 5.
Therefore, required output is 5.

Input: arr[] = {4, 4}
Output: 16
Explanation: All possible subarrays are {4}, {4, 4}, {4}.
Subarray 1: {4}. Maximum = 4. Sum = 1.
Subarray 2: {4, 4}. Maximum = 4. Since the maximum occurs twice in the subarray, Sum = 4 + 8 = 12.
Subarray 3: {4}. Maximum = 4. Sum = 16.
Therefore, required output is 16.

Naive Approach: The simplest approach to solve this problem is to generate all possible subarrays of the given array and find the maximum element in all subarrays along with the count of their occurrences. Finally, print the sum of all the maximum elements obtained. Follow the steps below to solve the problem:

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include``using` `namespace` `std;` `// Function to calculate sum of``// maximum of all subarrays``void` `findSum(vector<``int``>a)``{``    ``// Storeas the sum of maximums``    ``int` `ans = 0;` `    ``// Traverse the array``    ``for``(``int` `low = 0;``            ``low < a.size();``            ``low++)``    ``{``        ``for``(``int` `high = low;``                ``high < a.size();``                ``high++)``        ``{``            ` `            ``// Store the frequency of the``            ``// maximum element in subarray``            ``int` `count = 0;``            ``int` `maxNumber = 0;` `            ``// Finding maximum``            ``for``(``int` `i = low;``                    ``i <= high; i++)``            ``{``                ` `                ``// Increment frequency by 1``                ``if` `(a[i] == maxNumber)``                    ``count++;` `                ``// If new maximum is obtained``                ``else` `if` `(a[i] > maxNumber)``                ``{``                    ``maxNumber = a[i];``                    ``count = 1;``                ``}``            ``}` `            ``// If frequency of maximum``            ``// is even, then add 2*maxNumber.``            ``// Otherwise, add maxNumber``            ``ans += maxNumber * ((count % 2 == 0) ? 2 : 1);``        ``}``    ``}` `    ``// Print the sum obtained``    ``cout << (ans);``}` `// Driver Code``int` `main()``{``    ``vector<``int``>arr = { 2, 1, 4, 4, 2 };``    ` `    ``// Function Call``    ``findSum(arr);``}` `// This code is contributed by amreshkumar3`

## Java

 `// Java program for the above approach` `import` `java.io.*;` `class` `GFG {` `    ``// Function to calculate sum of``    ``// maximum of all subarrays``    ``public` `static` `void` `findSum(``int` `a[])``    ``{``        ``// Stores the sum of maximums``        ``int` `ans = ``0``;` `        ``// Traverse the array``        ``for` `(``int` `low = ``0``;``             ``low < a.length; low++) {` `            ``for` `(``int` `high = low;``                 ``high < a.length;``                 ``high++) {` `                ``// Store the frequency of the``                ``// maximum element in subarray``                ``int` `count = ``0``;``                ``int` `maxNumber = ``0``;` `                ``// Finding maximum``                ``for` `(``int` `i = low;``                     ``i <= high; i++) {` `                    ``// Increment frequency by 1``                    ``if` `(a[i] == maxNumber)``                        ``count++;` `                    ``// If new maximum is obtained``                    ``else` `if` `(a[i] > maxNumber) {``                        ``maxNumber = a[i];``                        ``count = ``1``;``                    ``}``                ``}` `                ``// If frequency of maximum``                ``// is even, then add 2*maxNumber.``                ``// Otherwise, add maxNumber``                ``ans += maxNumber``                       ``* ((count % ``2` `== ``0``) ? ``2` `: ``1``);``            ``}``        ``}` `        ``// Print the sum obtained``        ``System.out.println(ans);``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int``[] arr = { ``2``, ``1``, ``4``, ``4``, ``2` `};` `        ``// Function Call``        ``findSum(arr);``    ``}``}`

## Python3

 `# Python3 program for the above approach` `# Function to calculate sum of``# maximum of all subarrays``def` `findSum(a):``    ` `  ``# Stores the sum of maximums``  ``ans ``=` `0``  ` `  ``# Traverse the array``  ``for` `low ``in` `range``(``0``, ``len``(a)):``    ``for` `high ``in` `range``(low,``len``(a)):``        ` `      ``# Store the frequency of the``      ``# maximum element in subarray``      ``count ``=` `0``      ``maxNumber ``=` `0``      ` `      ``# Finding maximum``      ``for` `i ``in` `range``(low, high ``+` `1``):``          ` `        ``# Increment frequency by 1``        ``if` `(a[i] ``=``=` `maxNumber):``          ``count ``+``=` `1``          ` `        ``# If new maximum is obtained``        ``elif` `(a[i] > maxNumber):``          ``maxNumber ``=` `a[i]``          ``count ``=` `1` `      ``# If frequency of maximum``      ``# is even, then add 2*maxNumber.``      ``# Otherwise, add maxNumber``      ``if` `count ``%` `2``:``        ``ans ``+``=` `maxNumber``      ``else``:``        ``ans ``+``=` `maxNumber ``*` `2``        ` `  ``# Print the sum obtained``  ``print``(ans)``    ` `# Driver Code``arr ``=` `[ ``2``, ``1``, ``4``, ``4``, ``2` `]` `# Function Call``findSum(arr)` `# This code is contributed by rohitsingh07052`

## C#

 `// C# program for the above approach``using` `System;` `class` `GFG {` `  ``// Function to calculate sum of``  ``// maximum of all subarrays``  ``public` `static` `void` `findSum(``int``[] a)``  ``{``    ` `    ``// Stores the sum of maximums``    ``int` `ans = 0;` `    ``// Traverse the array``    ``for` `(``int` `low = 0; low < a.Length; low++) {` `      ``for` `(``int` `high = low; high < a.Length; high++) {` `        ``// Store the frequency of the``        ``// maximum element in subarray``        ``int` `count = 0;``        ``int` `maxNumber = 0;` `        ``// Finding maximum``        ``for` `(``int` `i = low; i <= high; i++) {` `          ``// Increment frequency by 1``          ``if` `(a[i] == maxNumber)``            ``count++;` `          ``// If new maximum is obtained``          ``else` `if` `(a[i] > maxNumber) {``            ``maxNumber = a[i];``            ``count = 1;``          ``}``        ``}` `        ``// If frequency of maximum``        ``// is even, then add 2*maxNumber.``        ``// Otherwise, add maxNumber``        ``ans += maxNumber``          ``* ((count % 2 == 0) ? 2 : 1);``      ``}``    ``}` `    ``// Print the sum obtained``    ``Console.WriteLine(ans);``  ``}` `  ``// Driver Code``  ``public` `static` `void` `Main()``  ``{``    ``int``[] arr = { 2, 1, 4, 4, 2 };` `    ``// Function Call``    ``findSum(arr);``  ``}``}` `// This code is contributed by ukasp.`

## Javascript

 ``
Output:
`75`

Time Complexity: O(N3)
Auxiliary Space: O(1)

Optimized Approach: To optimize the above approach, the idea is to store the prefix sums of every bit of array elements and find the frequency of the largest element in a subarray in O(1) computational complexity. This approach works as all the array elements are powers of 2.

Below is the implementation of the above approach:

## Java

 `// Java program for the above approach``import` `java.io.*;` `class` `GFG {` `    ``// Function to calculate sum of``    ``// maximum of all subarrays``    ``public` `static` `void` `findSum(``int` `a[])``    ``{``        ``// Calculate prefix sum array``        ``int``[][] prefixSums``            ``= getPrefixSums(a);` `        ``// Store the sum of maximums``        ``int` `ans = ``0``;` `        ``// Traverse the array``        ``for` `(``int` `low = ``0``;``             ``low < a.length;``             ``low++) {` `            ``for` `(``int` `high = low;``                 ``high < a.length;``                 ``high++) {` `                ``// Store the frequency of the``                ``// maximum element in subarray``                ``int` `count = ``0``;``                ``int` `maxNumber = ``0``;` `                ``// Store prefix sum of every bit``                ``for` `(``int` `i = ``30``; i >= ``0``; i--) {` `                    ``// Get the frequency of the``                    ``// largest element in subarray``                    ``count = getCountLargestNumber(``                        ``low, high, i, prefixSums);` `                    ``if` `(count > ``0``) {``                        ``maxNumber = (``1` `<< i);` `                        ``// If frequency of the largest``                        ``// element is even, add 2 * maxNumber``                        ``// Otherwise, add maxNumber``                        ``ans += maxNumber``                               ``* ((count % ``2` `== ``0``) ? ``2` `: ``1``);``                        ``break``;``                    ``}``                ``}``            ``}``        ``}` `        ``// Print the required answer``        ``System.out.println(ans);``    ``}` `    ``// Function to calculate the prefix``    ``// sum array``    ``public` `static` `int``[][] getPrefixSums(``        ``int``[] a)``    ``{` `        ``// Initialize prefix array``        ``int``[][] prefix = ``new` `int``[``32``][a.length + ``1``];` `        ``// Start traversing the array``        ``for` `(``int` `j = ``0``; j < a.length; j++) {` `            ``// Update the prefix array for``            ``// each element in the array``            ``for` `(``int` `i = ``0``; i <= ``30``; i++) {` `                ``// To check which bit is set``                ``int` `mask = (``1` `<< i);``                ``prefix[i][j + ``1``] += prefix[i][j];``                ``if` `((a[j] & mask) > ``0``)``                    ``prefix[i][j + ``1``]++;``            ``}``        ``}` `        ``// Return prefix array``        ``return` `prefix;``    ``}` `    ``// Function to find the maximum``    ``// in subarray {arr[low], ..., arr[high]}``    ``public` `static` `int``    ``getCountLargestNumber(``        ``int` `low, ``int` `high, ``int` `i,``        ``int``[][] prefixSums)``    ``{``        ``return` `prefixSums[i][high + ``1``]``            ``- prefixSums[i][low];``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int``[] arr = { ``2``, ``1``, ``4``, ``4``, ``2` `};` `        ``// Function Call``        ``findSum(arr);``    ``}``}`
Output:
`75`

Time Complexity: O(N2)
Auxiliary Space: O(32 * N)

Efficient Approach: To optimize the above approach, the idea is to use the property that all the array elements are powers of 2, and leverage that property to solve the problem. Follow the steps below to solve the problem:

• Iterate through all powers of 2 in descending order. Consider any arbitrary power of 2 as a mask.
• Divide the array into subarrays such that no subarray will contain arr[index] = -1, where an index is any valid position in the array.
• Let the subarray obtained from the above step be S. Traverse through S and add the values contributed by only the subarrays in S, which have the current mask, from the outer loop. Also set the corresponding position, where arr[index] = mask, to arr[index] = -1.
• To calculate the values contributed by all the subarrays in S that contains the mask and maintain three counters as oddCount, eventCount, and the frequency of mask.
• The pointer prev points to the previous index, such that arr[prev] = mask.
• At any index, where arr[index] = mask, get the count of integers between the last occurrence of the mask and the current occurrence by subtracting prev from the index. Use this count and the parity of frequency of mask, to get the values contributed by all contiguous subarrays that contain a mask, using the formula count = (index – prev) and add the count to the answer.
• If the frequency of the maximum is even or odd and if the parity is odd:
• Values contributed by all the contiguous subarrays that have the frequency of mask as odd is (count – 1)*evenCount + oddCount.
• Values contributed by all the contiguous subarrays that have the frequency of mask as even is 2*(count – 1)*oddCount + 2*evenCount.
• Otherwise, if the parity is even:
• Values contributed by all the contiguous subarrays that have the frequency of mask as odd is (count – 1)*oddCount + evenCount.
• Values contributed by all the contiguous subarrays that have the frequency of mask as even is 2*(count – 1) * evenCount + 2 * oddCount.
• Add all the corresponding values to the answer. Also add the count to evenCount if parity is even. Otherwise, add count to oddCount.

Below is the implementation of the above approach:

## Java

 `// Java program for the above approach``import` `java.io.*;` `class` `GFG {` `    ``// Function to calculate sum of``    ``// maximum of all subarrays``    ``public` `static` `void` `findSum(``int` `a[])``    ``{``        ``int` `ans = ``0``;``        ``int` `prev = -``1``;` `        ``// Iterate over the range [30, 0]``        ``for` `(``int` `i = ``30``; i >= ``0``; i--) {``            ``int` `mask = (``1` `<< i);` `            ``// Inner loop through the``            ``// length of the array``            ``for` `(``int` `j = ``0``;``                 ``j < a.length; j++) {` `                ``// Divide the array such``                ``// that no subarray will``                ``// have any index set to -1``                ``if` `(a[j] == -``1``) {``                    ``ans += findSumOfValuesOfRange(``                        ``a, prev + ``1``, j - ``1``, mask);``                    ``prev = j;``                ``}``            ``}` `            ``// Find the sum of subarray``            ``ans += findSumOfValuesOfRange(``                ``a, prev + ``1``, a.length - ``1``, mask);``        ``}` `        ``// Print the sum obtained``        ``System.out.println(ans);``    ``}` `    ``// Function that takes any subarray``    ``// S and return values contributed``    ``// by only the subarrays in S containing mask``    ``public` `static` `int` `findSumOfValuesOfRange(``        ``int``[] a, ``int` `low, ``int` `high, ``int` `mask)``    ``{``        ``if` `(low > high)``            ``return` `0``;` `        ``// Stores count even, odd count of``        ``// occurrences and maximum element``        ``int` `evenCount = ``0``, oddCount = ``0``,``            ``countLargestNumber = ``0``;``        ``int` `prev = low - ``1``, ans = ``0``;` `        ``// Traverse from low to high``        ``for` `(``int` `i = low; i <= high; i++) {` `            ``// Checking if this position``            ``// in the array is mask``            ``if` `((mask & a[i]) > ``0``) {` `                ``// Mask is the largest``                ``// number in subarray.``                ``// Increment count by 1``                ``countLargestNumber++;` `                ``// Store parity as 0 or 1``                ``int` `parity = countLargestNumber % ``2``;` `                ``// Setting a[i]=-1, this``                ``// will help in splitting``                ``// array into subarrays``                ``a[i] = -``1``;``                ``int` `count = i - prev;``                ``ans += count;` `                ``// Add values contributed``                ``// by those subarrays that``                ``// have an odd frequency``                ``ans += (count - ``1``)``                       ``* ((parity == ``1``) ? evenCount``                                        ``: oddCount);``                ``ans += ((parity == ``1``) ? oddCount``                                      ``: evenCount);` `                ``// Adding values contributed``                ``// by those subarrays that``                ``// have an even frequency``                ``ans += ``2` `* (count - ``1``)``                       ``* ((parity == ``1``) ? oddCount``                                        ``: evenCount);``                ``ans += ``2``                       ``* ((parity == ``1``) ? evenCount``                                        ``: oddCount);` `                ``// Set the prev pointer``                ``// to this position``                ``prev = i;` `                ``if` `(parity == ``1``)``                    ``oddCount += count;``                ``else``                    ``evenCount += count;``            ``}``        ``}` `        ``if` `(prev != low - ``1``) {``            ``int` `count = high - prev;``            ``int` `parity = countLargestNumber % ``2``;` `            ``ans += count``                   ``* ((parity == ``1``)``                          ``? oddCount``                          ``: evenCount);``            ``ans += ``2` `* count``                   ``* ((parity == ``1``)``                          ``? evenCount``                          ``: oddCount);``            ``ans *= mask;``        ``}` `        ``// Return the final sum``        ``return` `ans;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int``[] arr = { ``2``, ``1``, ``4``, ``4``, ``2` `};` `        ``// Function call``        ``findSum(arr);``    ``}``}`
Output:
`75`

Time Complexity: O(30*N)
Auxiliary Space: O(1)

My Personal Notes arrow_drop_up