Open In App

Sum of XOR of all possible subsets

Last Updated : 22 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array of size n, the task is to find the sum of all the values that come from XORing all the elements of the subsets

Examples:

Input: arr[] = [1, 2, 3]
Output: 28
Explanation: Subsets are: [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
0(empty subset)
1 = 1
2 = 2
3 = 3
1 ^ 2 = 3
1 ^ 3 = 2
2 ^ 3 = 1
1 ^ 2 ^ 3 = 0
Now SUM of all these XORs = 0 + 1 + 2 + 3 + 3 + 2 + 1 + 0 = 12

Input: arr[] = [7, 2]
Output: 6
Explanation: Subsets are: [[], [7], [2], [7, 2]]
Sum of all XOR's = 7 + 2 + (7 ^ 2) = 14.


[Naive Approach] Generate All Subsets Using Backtracking - O(n*2^n) Time and O(n*2^n) Space

The idea is to use backtracking to explore all possible choices one by one recursively. For each element, there two options, either include it into subset or exclude it. Finally calculate the xor sum for all subset.

State Space Tree for find all subsets using Backtracking:

Suppose an array of size 3 having elements [1, 2, 3], the state space tree can be constructed as below:

print-all-subsets

Follow the the steps below to implement the above idea:

  • Initialize an empty list subset to store the current subset elements, and a 2D list res to store all subsets.
  • Recursively iterate through the array elements.
    • Include (add) the current element to subset and recursively call the function for the next index.
    • Exclude (remove) the current element from subset to backtrack, and recursively call the function for the next index.
  • Calculate the XOR total for each subset.
  • Return the sum of the subset XOR totals.
C++
#include <iostream>
#include <vector>
#include <algorithm> 
using namespace std;

void subsetRecur(int i, vector<int>& arr, 
       vector<vector<int>>& res, vector<int>& subset) {
    
    // add subset at end of array
    if (i == arr.size()) {
        res.push_back(subset);
        return;
    }
    
    // include the current value and 
    // recursively find all subsets
    subset.push_back(arr[i]);
    subsetRecur(i+1, arr, res, subset);
    
    // exclude the current value and 
    // recursively find all subsets.
    subset.pop_back();
    subsetRecur(i+1, arr, res, subset);
}

int subsetXORSum(vector<int>& arr) {
    
    sort(arr.begin(),arr.end());
    vector<int> subset;
    vector<vector<int>> res;
    subsetRecur(0, arr, res, subset);
    int ans = 0;
    for(auto it:res){
        int Xor = 0;
        for(auto itt:it){
            Xor ^= itt;
        }
        ans += Xor;
    }

    return ans;
}

int main() {
    vector<int> arr = { 1, 2, 3 };
    int Xor = subsetXORSum(arr);
    cout<<Xor;
    return 0;
}
Java
import java.util.*;

class GfG {

    // include the current value and 
    // recursively find all subsets
    static void subsetRecur(int i, int[] arr,
             ArrayList<ArrayList<Integer>> res, ArrayList<Integer> subset) {
        if (i == arr.length) {
            res.add(new ArrayList<>(subset));
            return;
        }

        subset.add(arr[i]);
        subsetRecur(i + 1, arr, res, subset);

        // exclude the current value and 
        // recursively find all subsets.
        subset.remove(subset.size() - 1);
        subsetRecur(i + 1, arr, res, subset);
    }

    public static int subsetXORSum(int[] arr) {
        Arrays.sort(arr);
        ArrayList<Integer> subset = new ArrayList<>();
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        subsetRecur(0, arr, res, subset);

        int ans = 0;
        for (ArrayList<Integer> it : res) {
            int Xor = 0;
            for (int itt : it) {
                Xor ^= itt;
            }
            ans += Xor;
        }
        return ans;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        int Xor = subsetXORSum(arr);
        System.out.println(Xor);
    }
}
Python
def subsetRecur(i, arr, res, subset):
    # add subset at end of array
    if i == len(arr):
        res.append(subset[:])
        return
    
    # include the current value and 
    # recursively find all subsets
    subset.append(arr[i])
    subsetRecur(i + 1, arr, res, subset)
    
    # exclude the current value and 
    # recursively find all subsets.
    subset.pop()
    subsetRecur(i + 1, arr, res, subset)

def subsetXORSum(arr):
    arr.sort()
    subset = []
    res = []
    subsetRecur(0, arr, res, subset)
    
    ans = 0
    for it in res:
        xor_val = 0
        for val in it:
            xor_val ^= val
        ans += xor_val
    return ans

# Example usage
arr = [1, 2, 3]
Xor = subsetXORSum(arr)
print(Xor)
C#
using System;
using System.Collections.Generic;

class GfG{
    
    // include the current value and 
    // recursively find all subsets
    static void subsetRecur(int i, int[] arr, 
                      List<List<int>> res, List<int> subset){
        if (i == arr.Length){
            
            res.Add(new List<int>(subset));
            return;
        }

        subset.Add(arr[i]);
        subsetRecur(i + 1, arr, res, subset);

        // exclude the current value and 
        // recursively find all subsets.
        subset.RemoveAt(subset.Count - 1);
        subsetRecur(i + 1, arr, res, subset);
    }

    static int subsetXORSum(int[] arr){
        
        Array.Sort(arr);
        List<int> subset = new List<int>();
        List<List<int>> res = new List<List<int>>();
        subsetRecur(0, arr, res, subset);

        int ans = 0;
        foreach (var it in res){
            
            int Xor = 0;
            foreach (int itt in it){
                
                Xor ^= itt;
            }
            ans += Xor;
        }

        return ans;
    }

    static void Main(){
        
        int[] arr = { 1, 2, 3 };
        int Xor = subsetXORSum(arr);
        Console.WriteLine(Xor);
    }
}
JavaScript
function subsetRecur(i, arr, res, subset) {
    // add subset at end of array
    if (i === arr.length) {
        res.push([...subset]);
        return;
    }

    // include the current value and 
    // recursively find all subsets
    subset.push(arr[i]);
    subsetRecur(i + 1, arr, res, subset);

    // exclude the current value and 
    // recursively find all subsets.
    subset.pop();
    subsetRecur(i + 1, arr, res, subset);
}

function subsetXORSum(arr) {
    arr.sort((a, b) => a - b);
    let subset = [];
    let res = [];
    subsetRecur(0, arr, res, subset);

    let ans = 0;
    for (let it of res) {
        let xor = 0;
        for (let val of it) {
            xor ^= val;
        }
        ans += xor;
    }

    return ans;
}

// Example usage
let arr = [1, 2, 3];
let Xor = subsetXORSum(arr);
console.log(Xor);

Output
12

[Better Approach] Direct XOR of all possible Combinations - O(2^n) Time and O(n) Space

we use recursion to calculate the XOR sum while forming subsets. At each step, we choose to either include or exclude the current element and pass the updated XOR value accordingly. This way, we compute the total XOR of all subsets directly during recursion. The sum of both choices (with and without the current element) is returned to build the final answer efficiently.

Illustration:

1111
C++
// C++ program to find sum of 
// XOR of all possible subsets
#include<bits/stdc++.h>
using namespace std;

int xorRecur(int i, int sum, vector<int> &arr) {
    if (i==arr.size()) return sum;
    
    // include current element
    int take = xorRecur(i+1, sum^arr[i], arr);
    
    // exclude current element
    int noTake = xorRecur(i+1, sum, arr);
    
    // return sum of both
    return take + noTake;
}

int subsetXORSum(vector<int> &arr) {
    
    // Recursively find all the subsets
    // and return their xor sum
    return xorRecur(0, 0, arr);
}

int main() {
    vector<int> arr = {1, 2, 3};
    cout << subsetXORSum(arr) << endl;
    return 0;
}
Java
// Java program to find sum of 
// XOR of all possible subsets
import java.util.*;

class GfG {
    static int xorRecur(int i, int sum, int[] arr) {
        if (i == arr.length) return sum;

        // include current element
        int take = xorRecur(i + 1, sum ^ arr[i], arr);

        // exclude current element
        int noTake = xorRecur(i + 1, sum, arr);

        // return sum of both
        return take + noTake;
    }

    static int subsetXORSum(int[] arr) {
      
        // Recursively find all the subsets
        // and return their xor sum
        return xorRecur(0, 0, arr);
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println(subsetXORSum(arr));
    }
}
Python
# Python program to find sum of 
# XOR of all possible subsets

def xorRecur(i, sum, arr):
    if i == len(arr):
        return sum
    
    # include current element
    take = xorRecur(i + 1, sum ^ arr[i], arr)
    
    # exclude current element
    noTake = xorRecur(i + 1, sum, arr)
    
    # return sum of both
    return take + noTake

def subsetXORSum(arr):
  
    # Recursively find all the subsets
    # and return their xor sum
    return xorRecur(0, 0, arr)

if __name__ == "__main__":
    arr = [1, 2, 3]
    print(subsetXORSum(arr))
C#
// C# program to find sum of 
// XOR of all possible subsets
using System;

class GfG {
    static int xorRecur(int i, int sum, int[] arr) {
        if (i == arr.Length) return sum;

        // include current element
        int take = xorRecur(i + 1, sum ^ arr[i], arr);

        // exclude current element
        int noTake = xorRecur(i + 1, sum, arr);

        // return sum of both
        return take + noTake;
    }

    static int subsetXORSum(int[] arr) {
      
        // Recursively find all the subsets
        // and return their xor sum
        return xorRecur(0, 0, arr);
    }

    static void Main(string[] args) {
        int[] arr = {1, 2, 3};
        Console.WriteLine(subsetXORSum(arr));
    }
}
JavaScript
// JavaScript program to find sum of 
// XOR of all possible subsets

function xorRecur(i, sum, arr) {
    if (i === arr.length) return sum;

    // include current element
    const take = xorRecur(i + 1, sum ^ arr[i], arr);

    // exclude current element
    const noTake = xorRecur(i + 1, sum, arr);

    // return sum of both
    return take + noTake;
}

function subsetXORSum(arr) {
    // Recursively find all the subsets
    // and return their xor sum
    return xorRecur(0, 0, arr);
}

const arr = [1, 2, 3];
console.log(subsetXORSum(arr));

Output
12

[Expected Approach] Efficient XOR Sum with OR Mask - O(n) Time and O(1) Space

The idea is to find the pattern with respect to the property of XOR.

Taking examples:

arr[] = [7, 2] Output → 14 → 1110
arr[] = [1, 2, 3] Output → 12 → 110

So if we analyze all these binary numbers of the XORs, we can observe that set bit occurs at all the positions of i (0 to n-1) will exactly contribute to half of 2n. So we can easily impose these two conditions at each such position of i. 

  • If there is any value of arr[] that has set ith bit set, then exactly half of 2n subsets will be of the form, so they will contribute to 2n-1+i to the final sum.
  • If there is no value of arr[] that ith bit set, then we can say that there will be no term in all subsets that have a ith bit set.

Proof:

Case 1: 

  • Lets assume there are k elements in the array with ith bit set and k is not zero. 
  • So, to have a subset with i'th bit set in its xor, we need it to have odd number of elements with ith bit set.
  • Number of ways to choose elements with ith bit not set = 2(n-k) 
  • Number of ways to choose elements with ith bit set = kC1 + kC3 + kC5 .... = 2(k-1)
  • Total number of ways = 2(n-k) * 2(k-1) = 2(n-1).
  • Thus, the contribution towards sum becomes, 2(n-1) * 2 i = 2 (n+i-1)

Case 2: 

  • If no element has ith bit set, i.e. k = 0, the contribution of ith bit towards total sum remains 0.
  • Now the question boils down to check which position of element of the arr[] will be set or not. But here is some trick that we will not iterate for all elements one by one in spite of that we can simple take the OR of all such values and multiply with 2n-1

Examples: 

2222
C++
// C++ program to find sum of 
// XOR of all possible subsets
#include<bits/stdc++.h>
using namespace std;

int subsetXORSum(vector<int> &arr) {
    int n = arr.size();
    int bits = 0;

    // Finding bitwise OR of all elements
    for (int i=0; i < n; ++i)
        bits |= arr[i];

    int ans = bits * pow(2, n-1);

    return ans;
}

int main() {
    vector<int> arr = {1, 2, 3};
    cout << subsetXORSum(arr) << endl;
    return 0;
}
Java
// Java program to find sum of 
// XOR of all possible subsets
import java.util.*;

class GfG {
    static int subsetXORSum(int[] arr) {
        int n = arr.length;
        int bits = 0;

        // Finding bitwise OR of all elements
        for (int i = 0; i < n; ++i)
            bits |= arr[i];

        int ans = (int)(bits * Math.pow(2, n - 1));

        return ans;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println(subsetXORSum(arr));
    }
}
Python
# Python program to find sum of 
# XOR of all possible subsets

def subsetXORSum(arr):
    n = len(arr)
    bits = 0

    # Finding bitwise OR of all elements
    for i in range(n):
        bits |= arr[i]

    ans = bits * (2 ** (n - 1))

    return ans

if __name__ == "__main__":
    arr = [1, 2, 3]
    print(subsetXORSum(arr))
C#
// C# program to find sum of 
// XOR of all possible subsets
using System;

class GfG {
    static int subsetXORSum(int[] arr) {
        int n = arr.Length;
        int bits = 0;

        // Finding bitwise OR of all elements
        for (int i = 0; i < n; ++i)
            bits |= arr[i];

        int ans = (int)(bits * Math.Pow(2, n - 1));

        return ans;
    }

    static void Main(string[] args) {
        int[] arr = {1, 2, 3};
        Console.WriteLine(subsetXORSum(arr));
    }
}
JavaScript
// JavaScript program to find sum of 
// XOR of all possible subsets

function subsetXORSum(arr) {
    let n = arr.length;
    let bits = 0;

    // Finding bitwise OR of all elements
    for (let i = 0; i < n; ++i)
        bits |= arr[i];

    let ans = bits * Math.pow(2, n - 1);

    return ans;
}

const arr = [1, 2, 3];
console.log(subsetXORSum(arr));

Output
12

Related Problems: 
Given a set, find XOR of the XOR’s of all subsets. 
Find sum of sum of all sub-sequences


Next Article
Article Tags :
Practice Tags :

Similar Reads