Open In App

Find array such that no subarray has xor zero or Y

Given two integers X (1 ? X ? 15) and Y. The task is to find an array of the maximum possible length N such that all the elements in the array lie in between 1 and 2X and there exists no subarray such that xor value of the subarray is either 0 or Y. If there exist multiple answers then print any one of them. If no such array exists then print -1
Examples: 
 

Input: X = 3, Y = 5 
Output: 1 3 1 
(1 ^ 3) = 2 
(3 ^ 1) = 2 
(1 ^ 3 ^ 1) = 3
Input: X = 1, Y = 1 
Output: -1 
 

 

Approach: The main idea is to build the prefix-xor of the required array and then build the array from it. Let the prefix-xor array be pre[]
Now, XOR of any two pairs in the prefix array say (pre[l] ^ pre[r]) will represent the XOR of some sub-array of the original array i.e. arr[l + 1] ^ arr[l + 2] ^ … ^ arr[r]
Thus, the problem now reduces to construct an array from the elements of pre[] array such that no pair of elements have bitwise-xor equal to 0 or Y and its length should be maximal. 
Notice that no pair of numbers has a bitwise-xor sum equal to 0 simply means can’t use the same number twice
If Y ? 2X then no pair of numbers less than 2X will have a bitwise-xor equal to Y, so you can just use all the numbers from 1 to 2X – 1 in any order. Otherwise, you can think of the numbers forming pairs, where each pair consists of 2 numbers with a bitwise-xor sum equal to Y. From any pair, if you add one number to the array, you can’t add the other. However, the pairs are independent of each other: your choice in one pair doesn’t affect any other pair. Thus, you can just choose either number in any pair and add them in any order you want. After you construct array pre[], you can construct the original array using: arr[i] = pre[i] ^ pre[i – 1].
Below is the implementation of the above approach: 
 




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the maximum length array
void maxLengthArr(int x, int y)
{
    // To store if an element is
    // already taken or not
    bool ex[(1 << x)];
 
    // To store visited numbers
    ex[0] = 1;
    vector<int> pre({ 0 });
 
    // For all possible values of pre[]
    for (int i = 1; i < (1 << x); i++) {
 
        // If it is already taken
        if (ex[i ^ y])
            continue;
 
        pre.push_back(i);
        ex[i] = 1;
    }
 
    // Not possible
    if (pre.size() == 1) {
        cout << "-1";
        return;
    }
 
    // Print the array constructing it
    // from the prefix-xor array
    for (int i = 1; i < pre.size(); i++)
        cout << (pre[i] ^ pre[i - 1]) << " ";
}
 
// Driver code
int main()
{
    int X = 3, Y = 5;
 
    maxLengthArr(X, Y);
 
    return 0;
}




// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
// Function to find the maximum length array
static void maxLengthArr(int x, int y)
{
    // To store if an element is
    // already taken or not
    boolean[] ex = new boolean[(1 << x)];
 
    // To store visited numbers
    ex[0] = true;
    Vector<Integer> pre = new Vector<Integer>();
    pre.add(0);
     
    // For all possible values of pre[]
    for (int i = 1; i < (1 << x); i++)
    {
 
        // If it is already taken
        if (ex[i ^ y])
            continue;
 
        pre.add(i);
        ex[i] = true;
    }
 
    // Not possible
    if (pre.size() == 1)
    {
        System.out.print("-1");
        return;
    }
 
    // Print the array constructing it
    // from the prefix-xor array
    for (int i = 1; i < pre.size(); i++)
        System.out.print((pre.get(i) ^
                          pre.get(i - 1)) + " ");
}
 
// Driver code
public static void main(String[] args)
{
    int X = 3, Y = 5;
 
    maxLengthArr(X, Y);
}
}
 
// This code is contributed by 29AjayKumar




# Python3 implementation of the approach
 
# Function to find the maximum length array
def maxLengthArr(x, y) :
 
    # To store if an element is
    # already taken or not
    ex = [0] * (1 << x);
     
    # To store visited numbers
    ex[0] = 1;
    pre = [0];
     
    # For all possible values of pre[]
    for i in range(1, (1 << x)) :
         
        # If it is already taken
        if (ex[i ^ y]) :
            continue;
             
        pre.append(i);
        ex[i] = 1;
         
    # Not possible
    if (len(pre) == 1) :
        print("-1", end = "");
        return;
         
    # Print the array constructing it
    # from the prefix-xor array
    for i in range(1, len(pre)) :
        print(pre[i] ^ pre[i - 1], end = " ");
 
# Driver code
if __name__ == "__main__" :
     
    X = 3; Y = 5;
    maxLengthArr(X, Y);
 
# This code is contributed by AnkitRai01




// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // Function to find the maximum length array
    static void maxLengthArr(int x, int y)
    {
        // To store if an element is
        // already taken or not
        bool[] ex = new bool[(1 << x)];
 
        // To store visited numbers
        ex[0] = true;
        var pre = new List<int>();
        pre.Add(0);
 
        // For all possible values of pre[]
        for (int i = 1; i < (1 << x); i++)
        {
            // If it is already taken
            if (ex[i ^ y])
                continue;
 
            pre.Add(i);
            ex[i] = true;
        }
 
        // Not possible
        if (pre.Count == 1)
        {
            Console.Write("-1");
            return;
        }
 
        // Print the array constructing it
        // from the prefix-xor array
        for (int i = 1; i < pre.Count; i++)
            Console.Write((pre[i] ^ pre[i - 1]) + " ");
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int X = 3, Y = 5;
        maxLengthArr(X, Y);
    }
}
 
// This code is contributed by
// sanjeev2552




<script>
 
// Javascript implementation of the approach
 
// Function to find the maximum length array
function maxLengthArr(x, y)
{
    // To store if an element is
    // already taken or not
    let ex = new Array((1 << x)).fill(0);
 
    // To store visited numbers
    ex[0] = 1;
    let pre = [];
    pre.push(0);
 
    // For all possible values of pre[]
    for (let i = 1; i < (1 << x); i++) {
 
        // If it is already taken
        if (ex[i ^ y])
            continue;
 
        pre.push(i);
        ex[i] = 1;
    }
 
    // Not possible
    if (pre.length == 1) {
        document.write("-1");
        return;
    }
 
    // Print the array constructing it
    // from the prefix-xor array
    for (let i = 1; i < pre.length; i++)
        document.write((pre[i] ^ pre[i - 1]) + " ");
}
 
// Driver code
    let X = 3, Y = 5;
 
    maxLengthArr(X, Y);
     
</script>

Output: 
1 3 1

 

Time complexity: O(2x) where x is the given input

Auxiliary space: O(2x) where x is the given input

Related Topic: Subarrays, Subsequences, and Subsets in Array


Article Tags :