Open In App

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:
The subsets are {4, 2}, {2, 4} and {6}
Input: arr[] = {1, 2, 3}, k = 1 
Output:
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,

   


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 a[i] element in the k – 1 length subsets which can be done in k ways which explains the factor of k.
After computing the dp array, our answer will be

Below is the implementation of the above approach: 
 
// 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;
}

                    
// 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

                    
# 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

                    
// 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

                    
<?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
?>

                    
<script>
    // JavaScript implementation of the approach
     
    // Returns count of ordered subsets of arr[]
    // with XOR value = K
    function subsetXOR(arr, n, K)
    {
       
        // Find maximum element in arr[]
        let max_ele = arr[0];
        for (let i = 1; i < n; i++)
            if (arr[i] > max_ele)
                max_ele = arr[i];
       
        // Maximum possible XOR value
        let m =
        (1 << parseInt(Math.log(max_ele) / Math.log(2) + 1, 10)) - 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]
        let dp = new Array(n + 1);
       
        // Initializing all the values of
        // dp[i][j][k] as 0
        for (let i = 0; i <= n; i++)
        {
            dp[i] = new Array(m + 1);
            for (let j = 0; j <= m; j++)
            {
                dp[i][j] = new Array(n + 1);
                for (let k = 0; k <= n; k++)
                {
                    dp[i][j][k] = 0;
                }
            }
        }
       
        // The xor of empty subset is 0
        for (let i = 0; i <= n; i++)
            dp[i][0][0] = 1;
       
        // Fill the dp table
        for (let i = 1; i <= n; i++)
        {
            for (let j = 0; j <= m; j++)
            {
                for (let 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
        let ans = 0;
        for (let i = 1; i <= n; i++)
        {
            ans += dp[n][K][i];
        }
        return ans;
    }
     
    let arr = [ 1, 2, 3 ];
    let k = 1;
    let n = arr.length;
    document.write(subsetXOR(arr, n, k));
 
</script>

                    

Output: 
3

 

Time Complexity: O(n2 * m)
Auxiliary Space: O(n2 * m)


Article Tags :