Give an array of positive integers. The task is to find the total sum after performing the bitwise OR operation on all the sub-arrays of the given array.
Examples:
Input : arr[] = {1, 2, 3, 4, 5}
Output : 71
Input : arr[] = {6, 5, 4, 3, 2}
Output : 84
Explanation:

Simple Approach: A simple approach is to find the bitwise OR of each subarray of the given array using two nested loops, and then find the total sum. Time complexity of this approach will be O(N2).
Efficient Approach:
- Observe here that if a bit is being set by an element of the array then all subarray having that element will have that bit set. Therefore when we calculate sum of all subarrays having that number, we can directly multiply number of subarrays by the value that bit is making.
- Now, to do this an easy way will be to calculate the number of subarrays for which a bit is not set and subtract it from the total number of subarrays.
Let’s see an example:
Let the array A = [1, 2, 3, 4, 5]. Now the 1st bit is not set in the elements 2 and 4 and total number of such subarrays for which the Bitwise-OR will not have the 1st bit set will be 2.
Therefore, total number of subarrays for which the bitwise-OR will have 1st bit as set will be: 15-2 = 13.
Therefore we will add (13 * pow(2, 0)) to sum.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int givesum( int A[], int n)
{
int max = *max_element(A, A + n);
int maxBit = log2(max) + 1;
int totalSubarrays = n * (n + 1) / 2;
int s = 0;
for ( int i = 0; i < maxBit; i++) {
int c1 = 0;
vector< int > vec;
int sum = 0;
for ( int j = 0; j < n; j++) {
int a = A[j] >> i;
if (!(a & 1)) {
vec.push_back(j);
}
}
int cntSubarrNotSet = 0;
int cnt = 1;
for ( int j = 1; j < vec.size(); j++) {
if (vec[j] - vec[j - 1] == 1) {
cnt++;
}
else {
cntSubarrNotSet += cnt * (cnt + 1) / 2;
cnt = 1;
}
}
cntSubarrNotSet += cnt * (cnt + 1) / 2;
if (vec.size() == 0)
cntSubarrNotSet = 0;
int cntSubarrIthSet = totalSubarrays - cntSubarrNotSet;
s += cntSubarrIthSet * pow (2, i);
}
return s;
}
int main()
{
int A[] = { 1, 2, 3, 4, 5 };
int n = sizeof (A) / sizeof (A[0]);
cout << givesum(A, n);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int givesum( int A[], int n)
{
int max = Arrays.stream(A).max().getAsInt();
int maxBit = ( int )Math.ceil(Math.log(max) + 1 );
int totalSubarrays = n * (n + 1 ) / 2 ;
int s = 0 ;
for ( int i = 0 ; i < maxBit; i++) {
int c1 = 0 ;
Vector<Integer> vec = new Vector<>();
int sum = 0 ;
for ( int j = 0 ; j < n; j++) {
int a = A[j] >> i;
if (!(a % 2 == 1 )) {
vec.add(j);
}
}
int cntSubarrNotSet = 0 ;
int cnt = 1 ;
for ( int j = 1 ; j < vec.size(); j++) {
if (vec.get(j) - vec.get(j - 1 ) == 1 ) {
cnt++;
}
else {
cntSubarrNotSet += cnt * (cnt + 1 ) / 2 ;
cnt = 1 ;
}
}
cntSubarrNotSet += cnt * (cnt + 1 ) / 2 ;
if (vec.size() == 0 )
cntSubarrNotSet = 0 ;
int cntSubarrIthSet = totalSubarrays - cntSubarrNotSet;
s += cntSubarrIthSet * Math.pow( 2 , i);
}
return s;
}
public static void main(String[] args)
{
int A[] = { 1 , 2 , 3 , 4 , 5 };
int n = A.length;
System.out.println(givesum(A, n));
}
}
|
Python3
from math import log2
def givesum(A, n) :
max_element = max (A)
maxBit = int (log2(max_element)) + 1
totalSubarrays = n * (n + 1 ) / / 2
s = 0
for i in range (maxBit) :
c1 = 0
vec = []
sum = 0
for j in range (n) :
a = A[j] >> i
if ( not (a & 1 )) :
vec.append(j)
cntSubarrNotSet = 0
cnt = 1
for j in range ( 1 , len (vec)) :
if (vec[j] - vec[j - 1 ] = = 1 ) :
cnt + = 1
else :
cntSubarrNotSet + = cnt * (cnt + 1 ) / / 2
cnt = 1
cntSubarrNotSet + = cnt * (cnt + 1 ) / / 2
if len (vec) = = 0 :
cntSubarrNotSet = 0
cntSubarrIthSet = totalSubarrays - cntSubarrNotSet
s + = cntSubarrIthSet * pow ( 2 , i)
return s
if __name__ = = "__main__" :
A = [ 1 , 2 , 3 , 4 , 5 ]
n = len (A)
print (givesum(A, n))
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
class GFG {
static int givesum( int [] A, int n)
{
int max = A.Max();
int maxBit = ( int )Math.Ceiling(Math.Log(max) + 1);
int totalSubarrays = n * (n + 1) / 2;
int s = 0;
for ( int i = 0; i < maxBit; i++) {
List< int > vec = new List< int >();
for ( int j = 0; j < n; j++) {
int a = A[j] >> i;
if (!(a % 2 == 1)) {
vec.Add(j);
}
}
int cntSubarrNotSet = 0;
int cnt = 1;
for ( int j = 1; j < vec.Count; j++) {
if (vec[j] - vec[j - 1] == 1) {
cnt++;
}
else {
cntSubarrNotSet += cnt * (cnt + 1) / 2;
cnt = 1;
}
}
cntSubarrNotSet += cnt * (cnt + 1) / 2;
if (vec.Count() == 0)
cntSubarrNotSet = 0;
int cntSubarrIthSet = totalSubarrays - cntSubarrNotSet;
s += ( int )(cntSubarrIthSet * Math.Pow(2, i));
}
return s;
}
public static void Main()
{
int [] A = { 1, 2, 3, 4, 5 };
int n = A.Length;
Console.WriteLine(givesum(A, n));
}
}
|
PHP
<?php
function givesum( $A , $n )
{
$max = max( $A );
$maxBit = (int)((log( $max ) /
log10(2)) + 1);
$totalSubarrays = (int)( $n * ( $n + 1) / 2);
$s = 0;
for ( $i = 0; $i < $maxBit ; $i ++)
{
$c1 = 0;
$vec = array ();
$sum = 0;
for ( $j = 0; $j < $n ; $j ++)
{
$a = $A [ $j ] >> $i ;
if (!( $a & 1))
{
array_push ( $vec , $j );
}
}
$cntSubarrNotSet = 0;
$cnt = 1;
for ( $j = 1; $j < count ( $vec ); $j ++)
{
if ( $vec [ $j ] - $vec [ $j - 1] == 1)
{
$cnt ++;
}
else
{
$cntSubarrNotSet += (int)( $cnt *
( $cnt + 1) / 2);
$cnt = 1;
}
}
$cntSubarrNotSet += (int)( $cnt *
( $cnt + 1) / 2);
if ( count ( $vec ) == 0)
$cntSubarrNotSet = 0;
$cntSubarrIthSet = $totalSubarrays -
$cntSubarrNotSet ;
$s += $cntSubarrIthSet * pow(2, $i );
}
return $s ;
}
$A = array ( 1, 2, 3, 4, 5 );
$n = count ( $A );
echo givesum( $A , $n );
?>
|
Javascript
<script>
function givesum(A, n)
{
let max = Number.MIN_VALUE;
for (let i = 0; i < A.length; i++)
{
max = Math.max(max, A[i]);
}
let maxBit = Math.ceil(Math.log(max) + 1);
let totalSubarrays = n * (n + 1) / 2;
let s = 0;
for (let i = 0; i < maxBit; i++) {
let vec = [];
for (let j = 0; j < n; j++) {
let a = A[j] >> i;
if (!(a % 2 == 1)) {
vec.push(j);
}
}
let cntSubarrNotSet = 0;
let cnt = 1;
for (let j = 1; j < vec.length; j++) {
if (vec[j] - vec[j - 1] == 1) {
cnt++;
}
else {
cntSubarrNotSet += cnt * (cnt + 1) / 2;
cnt = 1;
}
}
cntSubarrNotSet += cnt * (cnt + 1) / 2;
if (vec.length == 0)
cntSubarrNotSet = 0;
let cntSubarrIthSet = totalSubarrays - cntSubarrNotSet;
s += parseInt(cntSubarrIthSet * Math.pow(2, i), 10);
}
return s;
}
let A = [ 1, 2, 3, 4, 5 ];
let n = A.length;
document.write(givesum(A, n));
</script>
|
Time Complexity: O(N*logN)
Auxiliary Space: O(log(MAX(A))) where max(A) is the maximum element in A.