Sum of XOR of all subarrays
Given an array containing N positive integers, the task is to find the sum of XOR of all sub-arrays of the array.
Examples:
Input : arr[] = {1, 3, 7, 9, 8, 7}
Output : 128
Input : arr[] = {3, 8, 13}
Output : 46
Explanation for second test-case:
XOR of {3} = 3
XOR of {3, 8} = 11
XOR of {3, 8, 13} = 6
XOR of {8} = 8
XOR of {8, 13} = 5
XOR of {13} = 13
Sum = 3 + 11 + 6 + 8 + 5 + 13 = 46
Simple solution: A simple solution will be to generate all the sub-arrays and then iterate through them all to find the required XOR values and then sum them up.
C++
#include <iostream>
#include <vector>
using namespace std;
int findXorSum( int arr[], int n)
{
int sum = 0;
for ( int i = 0; i < n; i++) {
int xorr = 0;
for ( int j = i; j < n; j++) {
xorr = xorr ^ arr[j];
sum += xorr;
}
}
return sum;
}
int main()
{
int arr[] = { 3, 8, 13 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << findXorSum(arr, n);
return 0;
}
|
Java
import java.util.Arrays;
public class Main {
public static int findXorSum( int [] arr, int n)
{
int sum = 0 ;
for ( int i = 0 ; i < n; i++) {
int xorr = 0 ;
for ( int j = i; j < n; j++) {
xorr = xorr ^ arr[j];
sum += xorr;
}
}
return sum;
}
public static void main(String[] args)
{
int [] arr = { 3 , 8 , 13 };
int n = arr.length;
System.out.println(findXorSum(arr, n));
}
}
|
Python3
def findXorSum(arr, n):
sum = 0
for i in range (n):
xorr = 0
for j in range (i, n):
xorr = xorr ^ arr[j]
sum + = xorr
return sum
arr = [ 3 , 8 , 13 ]
n = len (arr)
print (findXorSum(arr, n))
|
C#
using System;
class Gfg {
public static int findXorSum( int [] arr, int n)
{
int sum = 0;
for ( int i = 0; i < n; i++) {
int xorr = 0;
for ( int j = i; j < n; j++) {
xorr = xorr ^ arr[j];
sum += xorr;
}
}
return sum;
}
public static void Main( string [] args)
{
int [] arr = { 3, 8, 13 };
int n = arr.Length;
Console.WriteLine(findXorSum(arr, n));
}
}
|
Javascript
function findXorSum(arr, n)
{
let sum = 0;
for (let i = 0; i < n; i++){
let xorr = 0;
for (let j = i; j < n; j++){
xorr = xorr ^ arr[j];
sum += xorr;
}
}
return sum;
}
let arr = [ 3, 8, 13 ];
let n = arr.length;
console.log(findXorSum(arr, n));
|
Time Complexity: O(n*n)
Auxiliary Space: O(1)
Better solution: A better solution will be using a prefix array i.e. , for every index ‘i’ of the array ‘arr[]’ create a prefix array to store the XOR of all the elements from the left end of the array ‘arr[]’ up to the ith element of ‘arr[]’ Creating a prefix array will take a time of O(N).
Now, using this prefix array, we can find the XOR value of any sub-array in O(1) time.
We can find the XOR from index l to r using the formula:
if l is not zero
XOR = prefix[r] ^ prefix[l-1]
else
XOR = prefix[r].
After this, all we have to do is, to sum up, the XOR values of all the sub-arrays.
Since a total number of sub-arrays is of the order (N2), the time complexity of this approach will be O(N2).
Best solution: For the sake of better understanding, let’s assume any bit of an element is represented by the variable ‘i’ and the variable ‘sum’ is used to store the final sum.
The idea here is, we will try to find the number of XOR values with ith bit set. Let us suppose, there is ‘Si‘ number of sub-arrays with ith bit set. For, ith bit, the sum can be updated as sum += (2i * S)
So, the question is how to implement the above idea?
We will break the task into multiple steps. At each step, we will try to find the number of XOR values with ith bit set.
Now, we will break each step into sub-steps. In each sub-step, we will try to find the number of sub-arrays starting from an index ‘j'(where j varies between 0 to n – 1) with ith bit set in their XOR value. For, ith bit is to be set, an odd number of elements of the sub-array should have their ith bit set.
For all the bits, in a variable c_odd, we will store the count of the number of sub-arrays starting from j = 0 with ith bit set in an odd number of elements. Then, we will iterate through all the elements of the array updating the value of c_odd when needed. If we reach an element ‘j’ with ith bit set, we will update c_odd as c_odd = (n – j – c_odd). Its because, since we encountered a set bit, the number of sub-arrays with an even the number of elements with ith bit set will switch to a number of sub-arrays with an odd number of elements with ith bit set.
Below is the implementation of this approach:
C++
#include <iostream>
#include <vector>
using namespace std;
int findXorSum( int arr[], int n)
{
int sum = 0;
int mul = 1;
for ( int i = 0; i < 30; i++) {
int c_odd = 0;
bool odd = 0;
for ( int j = 0; j < n; j++) {
if ((arr[j] & (1 << i)) > 0)
odd = (!odd);
if (odd)
c_odd++;
}
for ( int j = 0; j < n; j++) {
sum += (mul * c_odd);
if ((arr[j] & (1 << i)) > 0)
c_odd = (n - j - c_odd);
}
mul *= 2;
}
return sum;
}
int main()
{
int arr[] = { 3, 8, 13 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << findXorSum(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int findXorSum( int arr[], int n)
{
int sum = 0 ;
int mul = 1 ;
for ( int i = 0 ; i < 30 ; i++)
{
int c_odd = 0 ;
boolean odd = false ;
for ( int j = 0 ; j < n; j++)
{
if ((arr[j] & ( 1 << i)) > 0 )
odd = (!odd);
if (odd)
c_odd++;
}
for ( int j = 0 ; j < n; j++)
{
sum += (mul * c_odd);
if ((arr[j] & ( 1 << i)) > 0 )
c_odd = (n - j - c_odd);
}
mul *= 2 ;
}
return sum;
}
public static void main(String[] args)
{
int arr[] = { 3 , 8 , 13 };
int n = arr.length;
System.out.println(findXorSum(arr, n));
}
}
|
Python3
def findXorSum(arr, n):
Sum = 0
mul = 1
for i in range ( 30 ):
c_odd = 0
odd = 0
for j in range (n):
if ((arr[j] & ( 1 << i)) > 0 ):
odd = (~odd)
if (odd):
c_odd + = 1
for j in range (n):
Sum + = (mul * c_odd)
if ((arr[j] & ( 1 << i)) > 0 ):
c_odd = (n - j - c_odd)
mul * = 2
return Sum
arr = [ 3 , 8 , 13 ]
n = len (arr)
print (findXorSum(arr, n))
|
C#
using System;
class GFG
{
static int findXorSum( int []arr, int n)
{
int sum = 0;
int mul = 1;
for ( int i = 0; i < 30; i++)
{
int c_odd = 0;
bool odd = false ;
for ( int j = 0; j < n; j++)
{
if ((arr[j] & (1 << i)) > 0)
odd = (!odd);
if (odd)
c_odd++;
}
for ( int j = 0; j < n; j++)
{
sum += (mul * c_odd);
if ((arr[j] & (1 << i)) > 0)
c_odd = (n - j - c_odd);
}
mul *= 2;
}
return sum;
}
static void Main()
{
int []arr = { 3, 8, 13 };
int n = arr.Length;
Console.WriteLine(findXorSum(arr, n));
}
}
|
PHP
<?php
function findXorSum( $arr , $n )
{
$sum = 0;
$mul = 1;
for ( $i = 0; $i < 30; $i ++)
{
$c_odd = 0;
$odd = 0;
for ( $j = 0; $j < $n ; $j ++)
{
if (( $arr [ $j ] & (1 << $i )) > 0)
$odd = (! $odd );
if ( $odd )
$c_odd ++;
}
for ( $j = 0; $j < $n ; $j ++)
{
$sum += ( $mul * $c_odd );
if (( $arr [ $j ] & (1 << $i )) > 0)
$c_odd = ( $n - $j - $c_odd );
}
$mul *= 2;
}
return $sum ;
}
$arr = array (3, 8, 13);
$n = sizeof( $arr );
echo findXorSum( $arr , $n );
?>
|
Javascript
<script>
function findXorSum(arr, n)
{
let sum = 0;
let mul = 1;
for (let i = 0; i < 30; i++) {
let c_odd = 0;
let odd = 0;
for (let j = 0; j < n; j++) {
if ((arr[j] & (1 << i)) > 0)
odd = (!odd);
if (odd)
c_odd++;
}
for (let j = 0; j < n; j++) {
sum += (mul * c_odd);
if ((arr[j] & (1 << i)) > 0)
c_odd = (n - j - c_odd);
}
mul *= 2;
}
return sum;
}
let arr = [ 3, 8, 13 ];
let n = arr.length;
document.write(findXorSum(arr, n));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Last Updated :
14 Feb, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...