Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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.

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<bits/stdc++.h>
using namespace std;
 
// Function to calculate sum of
// maximum of all subarrays
void findSum(vector<int>a)
{
    // Stores 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




<script>
 
      // JavaScript program for the above approach
       
      // Function to calculate sum of
      // maximum of all subarrays
      function findSum(a) {
      // Stores the sum of maximums
        var ans = 0;
 
        // Traverse the array
        for (var low = 0; low < a.length; low++) {
          for (var high = low; high < a.length; high++) {
            // Store the frequency of the
            // maximum element in subarray
            var count = 0;
            var maxNumber = 0;
 
            // Finding maximum
            for (var 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
        document.write(ans);
      }
 
      // Driver Code
      var arr = [2, 1, 4, 4, 2];
 
      // Function Call
      findSum(arr);
       
</script>


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:

C++




// c++ program for the above approach
#include<bits/stdc++.h>
using namespace std;
 
// Function to find the maximum
// in subarray {arr[low], ..., arr[high]}
int getCountLargestNumber(
  int low, int high, int i,
  vector<vector<int>> prefixSums);
 
// Function to calculate the prefix
// sum array
vector<vector<int>> getPrefixSums(
  vector<int> a);
 
// Function to calculate sum of
// maximum of all subarrays
void findSum(vector<int> a)
{
  // Calculate prefix sum array
  vector<vector<int>> prefixSums
    = getPrefixSums(a);
 
  // Store 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;
 
      // 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
  cout << ans;
}
 
// Function to calculate the prefix
// sum array
vector<vector<int>> getPrefixSums(
  vector<int> a)
{
 
  // Initialize prefix array
  vector<vector<int>> prefix(32, vector<int>(a.size() + 1, 0));
 
  // Start traversing the array
  for (int j = 0; j < a.size(); 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]}
int getCountLargestNumber(
  int low, int high, int i,
  vector<vector<int>> prefixSums)
{
  return prefixSums[i][high + 1]
    - prefixSums[i][low];
}
 
// Driver Code
int main()
{
  vector<int> arr = { 2, 1, 4, 4, 2 };
 
  // Function Call
  findSum(arr);
  return 0;
}
 
// This code is contributed
// by Shubham Singh


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);
    }
}


Python3




# Python program for the above approach
 
# Function to calculate sum of
# maximum of all subarrays
def findSum(a):
   
    # Calculate prefix sum array
    prefixSums = getPrefixSums(a);
 
    # Store the sum of maximums
    ans = 1;
 
    # Traverse the array
    for low in range(len(a)):
 
        for high in range(len(a)):
 
            # Store the frequency of the
            # maximum element in subarray
            count = 0;
            maxNumber = 0;
 
            # Store prefix sum of every bit
            for i in range(30,0,-1):
 
                # 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
                    if(count % 2 == 0):
                        ans += maxNumber * 2;
                    else:
                        ans += maxNumber *  1;
                    break;
                 
    # Print the required answer
    print(ans);
 
# Function to calculate the prefix
# sum array
def getPrefixSums(a):
 
    # Initialize prefix array
    prefix = [[0 for i in range(len(a)+1)] for j in range(32)];
 
    # Start traversing the array
    for j in range(len(a)):
 
        # Update the prefix array for
        # each element in the array
        for i in range(31):
 
            # To check which bit is set
            mask = (1 << i);
            prefix[i][j + 1] += prefix[i][j];
            if ((a[j] & mask) > 0):
                prefix[i][j + 1]+=1;
         
    # Return prefix array
    return prefix;
 
# Function to find the maximum
# in subarray:arr[low], ..., arr[high]
def getCountLargestNumber(low, high, i, prefixSums):
    return prefixSums[i][high + 1] - prefixSums[i][low];
 
# Driver Code
if __name__ == '__main__':
    arr = [ 2, 1, 4, 4, 2 ];
 
    # Function Call
    findSum(arr);
 
# This code is contributed by gauravrajput1


C#




// C# program for the above approach
 
 
using System;
public 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
        Console.WriteLine(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);
    }
}
 
// This code is contributed by gauravrajput1


Javascript




<script>
// javascript program for the above approach
 
    // Function to calculate sum of
    // maximum of all subarrays
    function findSum(a)
    {
     
        // Calculate prefix sum array
        var prefixSums = getPrefixSums(a);
 
        // Store the sum of maximums
        var ans = 0;
 
        // Traverse the array
        for (var low = 0; low < a.length; low++) {
 
            for (var high = low; high < a.length; high++) {
 
                // Store the frequency of the
                // maximum element in subarray
                var count = 0;
                var maxNumber = 0;
 
                // Store prefix sum of every bit
                for (var 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
        document.write(ans);
    }
 
    // Function to calculate the prefix
    // sum array
      function getPrefixSums(a) {
 
        // Initialize prefix array
        var prefix = Array(32).fill().map(()=>Array(a.length + 1).fill(0));
 
        // Start traversing the array
        for (var j = 0; j < a.length; j++) {
 
            // Update the prefix array for
            // each element in the array
            for (var i = 0; i <= 30; i++) {
 
                // To check which bit is set
                var 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]}
    function getCountLargestNumber(low , high , i, prefixSums) {
        return prefixSums[i][high + 1] - prefixSums[i][low];
    }
 
    // Driver Code
        var arr = [ 2, 1, 4, 4, 2 ];
 
        // Function Call
        findSum(arr);
 
// This code is contributed by gauravrajput1
</script>


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:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
 
using namespace std;
 
// Function that takes any subarray
// S and return values contributed
// by only the subarrays in S containing mask
int findSumOfValuesOfRange(vector<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])) {
 
      // Mask is the largest
      // number in subarray.
      // Increment count by 1
      countLargestNumber++;
 
      // Store parity as 0 or 1
      int parity = countLargestNumber & 1;
 
      // 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) ? evenCount : oddCount);
      ans += ((parity) ? oddCount : evenCount);
 
      // Adding values contributed
      // by those subarrays that
      // have an even frequency
      ans += 2 * (count - 1)
        * ((parity) ? oddCount : evenCount);
      ans += 2
        * ((parity) ? 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) ? oddCount : evenCount);
    ans += 2 * count
      * ((parity) ? evenCount : oddCount);
    ans *= mask;
  }
 
  // Return the readonly sum
  return ans;
}
// Function to calculate sum of
// maximum of all subarrays
void findSum(vector<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.size(); 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.size() - 1, mask);
  }
 
  // Print the sum obtained
  cout << ans << endl;
}
 
 
 
// Driver Code
int main()
{
  vector<int> arr = { 2, 1, 4, 4,  2 };
 
  // Function call
  findSum(arr);
}
 
// This code is contributed by phasing17


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);
    }
}


Python3




# Python program for the above approach
 
# Function to calculate sum of
# maximum of all subarrays
def findSum(a):
    ans = 0
    prev = -1
 
    # Iterate over the range [30, 0]
    for i in range(30,-1,-1):
        mask = (1 << i)
 
        # Inner loop through the
        # length of the array
        for j in range(len(a)):
 
            # 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, len(a) - 1, mask)
 
    # Print the sum obtained
    print(ans)
 
# Function that takes any subarray
# S and return values contributed
# by only the subarrays in S containing mask
def findSumOfValuesOfRange(a , low , high , mask):
    if (low > high):
        return 0
 
    # Stores count even, odd count of
    # occurrences and maximum element
    evenCount,oddCount,countLargestNumber = 0,0,0
    prev,ans = low - 1,0
 
    # Traverse from low to high
    for i in range(low,high + 1):
 
        # 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 += 1
 
            # Store parity as 0 or 1
            parity = countLargestNumber % 2
 
            # Setting a[i]=-1, this
            # will help in splitting
            # array into subarrays
            a[i] = -1
            count = i - prev
            ans += count
 
            # Add values contributed
            # by those subarrays that
            # have an odd frequency
            ans += (count - 1) * (evenCount if (parity == 1) else oddCount)
            ans += (oddCount if (parity == 1) else evenCount)
 
            # Adding values contributed
            # by those subarrays that
            # have an even frequency
            ans += 2 * (count - 1) * (oddCount if (parity == 1) else evenCount)
            ans += 2 * (evenCount if (parity == 1) else oddCount)
 
            # Set the prev pointer
            # to this position
            prev = i
 
            if (parity == 1):
                oddCount += count
            else:
                evenCount += count
 
    if (prev != low - 1):
        count = high - prev
        parity = countLargestNumber % 2
 
        ans += count * (oddCount if (parity == 1) else evenCount)
        ans += 2 * count * (evenCount if (parity == 1) else oddCount)
        ans *= mask
 
    # Return the final sum
    return ans
 
# Driver Code
arr = [ 2, 1, 4, 4, 2 ]
 
# function call
findSum(arr)
 
# This code is contributed by shinjanpatra


C#




// C# program for the above approach
using System;
public 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
        Console.WriteLine(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 readonly sum
        return ans;
    }
 
    // Driver Code
    public static void Main(String[] args) {
        int[] arr = { 2, 1, 4, 4, 2 };
 
        // Function call
        findSum(arr);
    }
}
 
// This code is contributed by gauravrajput1


Javascript




<script>
// javascript program for the above approach
 
    // Function to calculate sum of
    // maximum of all subarrays
    function findSum(a) {
        var ans = 0;
        var prev = -1;
 
        // Iterate over the range [30, 0]
        for (var i = 30; i >= 0; i--) {
            var mask = (1 << i);
 
            // Inner loop through the
            // length of the array
            for (var 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
        document.write(ans);
    }
 
    // Function that takes any subarray
    // S and return values contributed
    // by only the subarrays in S containing mask
    function findSumOfValuesOfRange(a , low , high , mask) {
        if (low > high)
            return 0;
 
        // Stores count even, odd count of
        // occurrences and maximum element
        var evenCount = 0, oddCount = 0, countLargestNumber = 0;
        var prev = low - 1, ans = 0;
 
        // Traverse from low to high
        for (var 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
                var parity = countLargestNumber % 2;
 
                // Setting a[i]=-1, this
                // will help in splitting
                // array into subarrays
                a[i] = -1;
                var 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) {
            var count = high - prev;
            var 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
        var arr = [ 2, 1, 4, 4, 2 ];
 
        // Function call
        findSum(arr);
 
// This code is contributed by gauravrajput1
</script>


Output: 

75

 

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

Related Topic: Subarrays, Subsequences, and Subsets in Array



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