Count no. of ordered subsets having a particular XOR value
Last Updated :
18 Apr, 2023
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 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
$ \sum_{k=1}^{k=n} dp[n][K][k] $
Below is the implementation of the above approach:
C++
// 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
// 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
Python3
# 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#
// 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
// 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
?>
JavaScript
<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>
Time Complexity: O(n2 * m)
Auxiliary Space: O(n2 * m)
Similar Reads
Count of subsets having maximum possible XOR value Given an array arr[] consisting of N positive integers. The task is to count the number of different non-empty subsets of arr[] having maximum bitwise XOR. Examples: Input: arr[] = {3, 1}Output: 1Explanation: The maximum possible bitwise XOR of a subset is 3. In arr[] there is only one subset with b
6 min read
Count distinct possible Bitwise XOR values of subsets of an array Given an array arr[] consisting of N integers, the task is to find the size of the set S such that Bitwise XOR of any subset of the array arr[] exists in the set S. Examples: Input: arr[] = {1, 2, 3, 4, 5}Output: 8Explanation:All possible Bitwise XOR values of subsets of the array arr[] are {0, 1, 2
14 min read
Count of unique subsets from a set having repeated elements Given an array arr[] of size N. The task is to count the number of unique subsets. Examples: Input: arr[] = {1, 2, 2}Output: 6Explanation: Total possible subsets of this set = 2³= 8. Following are the all 8 subsets formed from arr[].{}, {1}, {2}, {2}, {1, 2}, {1, 2}, {2, 2}, {1, 2, 2}. These are all
5 min read
Number of subsets with same AND, OR and XOR values in an Array Given an array arr[] of size N consisting of non-negative integers, the task is to find the number of non-empty subsets of the array such that the bitwise AND, bitwise OR and bitwise XOR values of the subsequence are equal to each other. Note: Since the answer can be large, mod it with 1000000007. E
14 min read
Count subsequences having odd Bitwise XOR values from an array Given an array A[] of size N, the task is to count the number of subsequences from the given array whose Bitwise XOR value is odd. Examples: Input: A[] = {1, 3, 4}Output: 4Explanation: Subsequences with odd Bitwise XOR are {1}, {3}, {1, 4}, {3, 4}. Input: A[] = {2, 8, 6}Output: 0Explanation: No such
5 min read