Sum of maximum of all subarrays by adding even frequent maximum twice
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:
- Initialize a variable, say sum, to store the required sum of maximum of all subarrays.
- Generate all possible subarrays of the given array arr[].
- For each subarray generated, find the frequency of the largest element and check if the frequency is even or not. If found to be true, add 2 * maximum to sum. Otherwise, add maximum to sum.
- After completing the above steps, print the value of sum as the result.
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> |
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> |
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> |
75
Time Complexity: O(30*N)
Auxiliary Space: O(1)
Related Topic: Subarrays, Subsequences, and Subsets in Array
Please Login to comment...