Count no. of ordered subsets having a particular XOR value

Given an array arr[] of n elements and a number K, find the number of ordered subsets of arr[] having XOR of elements as K
This is a modified version of this problem. So it is recommended to try that problem before.

Examples:

Input: arr[] = {6, 9, 4, 2}, k = 6
Output: 2
The subsets are {4, 2}, {2, 4} and {6}



Input: arr[] = {1, 2, 3}, k = 1
Output: 4
The subsets are {1}, {2, 3} and {3, 2}

Naive Approach O(2n): Generate all the 2n subsets and find all the subsets having XOR value K and for each subset with XOR value K, add no. of permutations of that subset to the answer since we are required ordered subsets, but this approach will not be efficient for large values of n.

Efficient Approach O(n2 * m): This approach uses dynamic programming which is similar to the approach explained in this article.
Only modification is that we add one more state to our solution. There we had two states where dp[i][j] stored the no. of subsets of the array[0…i-1] having XOR value j. Now, we add one more state k, i.e. a third dimension that stores the length of the subsets.
So, dp[i][j][k] will store the no. of subsets of length k of the array[0…i-1] having XOR value j.

Now we can see that,

     $$ dp[i][j][k] = dp[i-1][j][k] + k*dp[i-1][a[i-1] XOR j][k-1] $$

i.e. dp[i][j][k] can be found by discarding the a[i] element(which gives dp[i-1][j][k] subsets) and taking it in the subset(Similar idea to Subset Sum Problem) which gives dp[i-1][a[i] ^ j][k-1] subsets. Now we have to insert the the a[i] element in the k – 1 length subsets which can be done in k ways which explains the factor of k.

After comupting the dp array, our answer will be

 $ \sum_{k=1}^{k=n} dp[n][K][k] $

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Returns count of ordered subsets of arr[]
// with XOR value = K
int subsetXOR(int arr[], int n, int K)
{
  
    // Find maximum element in arr[]
    int max_ele = arr[0];
    for (int i = 1; i < n; i++)
        if (arr[i] > max_ele)
            max_ele = arr[i];
  
    // Maximum possible XOR value
    int m = (1 << (int)(log2(max_ele) + 1)) - 1;
  
    // The value of dp[i][j][k] is the number 
    // of subsets of length k having XOR of their 
    // elements as j from the set arr[0...i-1]
    int dp[n + 1][m + 1][n + 1];
  
    // Initializing all the values of dp[i][j][k]
    // as 0
    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= m; j++)
            for (int k = 0; k <= n; k++)
                dp[i][j][k] = 0;
  
    // The xor of empty subset is 0
    for (int i = 0; i <= n; i++)
        dp[i][0][0] = 1;
  
    // Fill the dp table
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            for (int k = 0; k <= n; k++) {
                dp[i][j][k] = dp[i - 1][j][k];
                if (k != 0) {
                    dp[i][j][k] += k * dp[i - 1][j ^ 
                                   arr[i - 1]][k - 1];
                }
            }
        }
    }
  
    // The answer is the number of subsets of all lengths
    // from set arr[0..n-1] having XOR of elements as k
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        ans += dp[n][K][i];
    }
    return ans;
}
  
// Driver program to test above function
int main()
{
    int arr[] = { 1, 2, 3 };
    int k = 1;
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << subsetXOR(arr, n, k);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG
{
    // Returns count of ordered subsets of arr[]
    // with XOR value = K
    static int subsetXOR(int arr[], int n, int K)
    {
      
        // Find maximum element in arr[]
        int max_ele = arr[0];
        for (int i = 1; i < n; i++)
            if (arr[i] > max_ele)
                max_ele = arr[i];
      
        // Maximum possible XOR value
        int m = (1 << (int)(Math.log(max_ele) / 
                        Math.log(2) + 1)) - 1;
      
        // The value of dp[i][j][k] is the number 
        // of subsets of length k having XOR of their 
        // elements as j from the set arr[0...i-1]
        int [][][] dp = new int[n + 1][m + 1][n + 1];
      
        // Initializing all the values of 
        // dp[i][j][k] as 0
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= m; j++)
                for (int k = 0; k <= n; k++)
                    dp[i][j][k] = 0;
      
        // The xor of empty subset is 0
        for (int i = 0; i <= n; i++)
            dp[i][0][0] = 1;
      
        // Fill the dp table
        for (int i = 1; i <= n; i++) 
        {
            for (int j = 0; j <= m; j++) 
            {
                for (int k = 0; k <= n; k++) 
                {
                    dp[i][j][k] = dp[i - 1][j][k];
                    if (k != 0)
                    {
                        dp[i][j][k] += k * dp[i - 1][j ^ 
                                    arr[i - 1]][k - 1];
                    }
                }
            }
        }
      
        // The answer is the number of subsets 
        // of all lengths from set arr[0..n-1]
        // having XOR of elements as k
        int ans = 0;
        for (int i = 1; i <= n; i++) 
        {
            ans += dp[n][K][i];
        }
        return ans;
    }
      
    // Driver code
    public static void main(String []args)
    {
        int arr[] = { 1, 2, 3 };
        int k = 1;
        int n = arr.length;
        System.out.println(subsetXOR(arr, n, k));
    }
}
  
// This code is contributed by ihritik

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3implementation of the approach
from math import log2
  
# Returns count of ordered subsets of arr[]
# with XOR value = K
def subsetXOR(arr, n, K):
      
    # Find maximum element in arr[]
    max_ele = arr[0]
    for i in range(1, n):
        if (arr[i] > max_ele):
            max_ele = arr[i]
  
    # Maximum possible XOR value
    m = (1 << int(log2(max_ele) + 1)) - 1
  
    # The value of dp[i][j][k] is the number 
    # of subsets of length k having XOR of their 
    # elements as j from the set arr[0...i-1]
    dp = [[[0 for i in range(n + 1)] 
              for j in range(m + 1)] 
              for k in range(n + 1)]
  
    # Initializing all the values 
    # of dp[i][j][k] as 0
    for i in range(n + 1):
        for j in range(m + 1):
            for k in range(n + 1):
                dp[i][j][k] = 0
  
    # The xor of empty subset is 0
    for i in range(n + 1):
        dp[i][0][0] = 1
  
    # Fill the dp table
    for i in range(1, n + 1):
        for j in range(m + 1):
            for k in range(n + 1):
                dp[i][j][k] = dp[i - 1][j][k]
                if (k != 0):
                    dp[i][j][k] += k * dp[i - 1][j ^ arr[i - 1]][k - 1]
  
    # The answer is the number of subsets of all lengths
    # from set arr[0..n-1] having XOR of elements as k
    ans = 0
    for i in range(1, n + 1):
        ans += dp[n][K][i]
      
    return ans
  
# Driver Code
if __name__ == '__main__':
    arr = [1, 2, 3]
    k = 1
    n = len(arr)
    print(subsetXOR(arr, n, k))
      
# This code is contributed by
# Surendra_Gangwar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
  
class GFG
{
    // Returns count of ordered subsets of arr[]
    // with XOR value = K
    static int subsetXOR(int []arr, int n, int K)
    {
      
        // Find maximum element in arr[]
        int max_ele = arr[0];
        for (int i = 1; i < n; i++)
            if (arr[i] > max_ele)
                max_ele = arr[i];
      
        // Maximum possible XOR value
        int m = (1 << (int)(Math.Log(max_ele) / 
                        Math.Log(2) + 1)) - 1;
      
        // The value of dp[i][j][k] is the number 
        // of subsets of length k having XOR of their 
        // elements as j from the set arr[0...i-1]
        int [ , , ] dp = new int[n + 1 , m + 1 ,n + 1];
      
        // Initializing all the values of 
        // dp[i][j][k] as 0
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= m; j++)
                for (int k = 0; k <= n; k++)
                    dp[i, j, k] = 0;
      
        // The xor of empty subset is 0
        for (int i = 0; i <= n; i++)
            dp[i, 0, 0] = 1;
      
        // Fill the dp table
        for (int i = 1; i <= n; i++) 
        {
            for (int j = 0; j <= m; j++)
            {
                for (int k = 0; k <= n; k++)
                {
                    dp[i, j, k] = dp[i - 1, j, k];
                    if (k != 0) {
                        dp[i, j, k] += k * dp[i - 1, j ^ 
                                    arr[i - 1], k - 1];
                    }
                }
            }
        }
      
        // The answer is the number of subsets 
        // of all lengths from set arr[0..n-1] 
        // having XOR of elements as k
        int ans = 0;
        for (int i = 1; i <= n; i++) 
        {
            ans += dp[n, K, i];
        }
        return ans;
    }
      
    // Driver code
    public static void Main()
    {
        int []arr = { 1, 2, 3 };
        int k = 1;
        int n = arr.Length;
        Console.WriteLine(subsetXOR(arr, n, k));
    }
}
  
// This code is contributed by ihritik

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// Php implementation of above approach 
  
// Returns count of ordered subsets 
// of arr[] with XOR value = K 
function subsetXOR($arr, $n, $K
  
    // Find maximum element in arr[] 
    $max_ele = $arr[0]; 
    for ($i = 1; $i < $n; $i++) 
        if ($arr[$i] > $max_ele
            $max_ele = $arr[$i]; 
  
    // Maximum possible XOR value 
    $m = (1 << (floor(log($max_ele, 2))+ 1)) - 1; 
  
    // The value of dp[i][j][k] is the number 
    // of subsets of length k having XOR of their 
    // elements as j from the set arr[0...i-1] 
    $dp = array(array(array())) ;
  
    // Initializing all the values 
    // of dp[i][j][k] as 0 
    for ($i = 0; $i <= $n; $i++) 
        for ($j = 0; $j <= $m; $j++) 
            for ($k = 0; $k <= $n; $k++) 
                $dp[$i][$j][$k] = 0; 
  
    // The xor of empty subset is 0 
    for ($i = 0; $i <= $n; $i++) 
        $dp[$i][0][0] = 1; 
  
    // Fill the dp table 
    for ($i = 1; $i <= $n; $i++)
    
        for ($j = 0; $j <= $m; $j++) 
        
            for ($k = 0; $k <= $n; $k++) 
            
                $dp[$i][$j][$k] = $dp[$i - 1][$j][$k]; 
                if ($k != 0) 
                
                    $dp[$i][$j][$k] += $k * $dp[$i - 1][$j ^
                                       $arr[$i - 1]][$k - 1]; 
                
            
        
    
  
    // The answer is the number of subsets 
    // of all lengths from set arr[0..n-1] 
    // having XOR of elements as k 
    $ans = 0; 
    for ($i = 1; $i <= $n; $i++) 
    
        $ans += $dp[$n][$K][$i]; 
    
    return $ans
  
// Driver Code
$arr = [ 1, 2, 3 ]; 
$k = 1; 
$n = sizeof($arr); 
echo subsetXOR($arr, $n, $k); 
  
// This code is contributed by Ryuga
?>

chevron_right


Output:

3


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.