Open In App

XOR Queries on a given set

Given a set S with the initial element 0 that is S = { 0 }. The task is to perform each query when Q number of queries are given and print the answer after every query of type 3. 
We can perform three types of query operations: 
 

Examples: 
 



Input: Q = 10, 

1 7 

2 4 
2 8 
2 3 
1 10 
1 3 

2 1 
Output: 0 0 3
Explanation: 
For the given 10 queries, the changes in the set for each query is as follows: 
 

  1. The minimum is 0.
  2. The number 7 added to S –> {0, 7}.
  3. The minimum is still 0.
  4. All of the numbers in S are changed to their xor with 4 –> {4, 3}.
  5. All of the numbers in S are changed to their xor with 8 –> {12, 11}.
  6. All of the numbers in S are changed to their xor with 3 –> {15, 8}.
  7. The number 10 added to S –> {15, 8 ,10}.
  8. The number 3 added to S –> {15, 8, 10, 3}.
  9. The minimum is now 3.
  10. All of the numbers in S are changed to their xor with 1 –> {14, 9, 11, 2}.

Input: Q = 6 

1 7 

1 4 
2 8 

Output: 0 0 8 
 



 

Prerequisite: Trie.
Approach: 
We will try to solve this problem by using the trie approach of Minimum XOR Value Pair Problem. 
 

Now, coming to our problem. 
 

Below are the implementations of this approach:
 




// C++ program to operate
// queries in a given set
#include <bits/stdc++.h>
using namespace std;
 
const int Maxbits = 30;
 
// Function for Query 1
void Insert(int x, int curx,
            int* sz, int trie[100][2])
{
    // XOR each element before
    // storing it in the trie.
    x = x ^ curx;
    int p = 0;
 
    // Storing xored element in the trie.
    for (int i = Maxbits - 1; i >= 0; i--)
    {
        if (!trie[p][x >> i & 1])
            trie[p][x >> i & 1] = (*sz)++;
 
        p = trie[p][x >> i & 1];
    }
}
 
// Function for Query 2
void XorQuery(int x, int* curx)
{
    // Simply xor-ing all the number which
    // was asked to xor with the set elements.
    (*curx) = (*curx) ^ x;
}
 
// Function for Query 3
void MinXor(int x, int trie[100][2])
{
    int ans = 0, p = 0;
 
    // Finding the minimum element by checking
    // if x[i] bit is same with trie element.
    for (int i = Maxbits - 1; i >= 0; i--)
    {
        bool Currbit = (x >> i & 1);
 
        if (trie[p][Currbit])
            p = trie[p][Currbit];
 
        else {
            p = trie[p][!Currbit];
            ans |= 1 << i;
        }
    }
 
    cout << ans << endl;
}
 
// Driver code
int main()
{
    int sz = 1;
    int curx = 0;
    int trie[100][2] = { 0 };
 
    // Initialising the trie
    Insert(0, 0, &sz, trie);
 
    // Calling the Query
    MinXor(curx, trie);
    Insert(7, curx, &sz, trie);
    MinXor(curx, trie);
    XorQuery(4, &curx);
    XorQuery(8, &curx);
    XorQuery(3, &curx);
    Insert(10, curx, &sz, trie);
    Insert(3, curx, &sz, trie);
    MinXor(curx, trie);
    XorQuery(1, &curx);
 
    return 0;
}




//Java code for the above approach
import java.util.Scanner;
 
class GFG{
  static final int Maxbits = 30;
  static int sz = 1;
  static int curx = 0;
  static int[][] trie = new int[100][2];
 
  // Function for Query 1
  static void Insert(int x, int curx) {
    // XOR each element before
    // storing it in the trie.
    x = x ^ curx;
    int p = 0;
 
    // Storing xored element in the trie.
    for (int i = Maxbits - 1; i >= 0; i--) {
      if (trie[p][x >> i & 1] == 0)
        trie[p][x >> i & 1] = sz++;
 
      p = trie[p][x >> i & 1];
    }
  }
 
  // Function for Query 2
  static void XorQuery(int x) {
    // Simply xor-ing all the number which
    // was asked to xor with the set elements.
    curx = curx ^ x;
  }
 
  // Function for Query 3
  static void MinXor(int x) {
    int ans = 0, p = 0;
 
    // Finding the minimum element by checking
    // if x[i] bit is same with trie element.
    for (int i = Maxbits - 1; i >= 0; i--) {
      boolean Currbit = (x >> i & 1) == 1;
 
      if (trie[p][Currbit ? 1 : 0] != 0)
        p = trie[p][Currbit ? 1 : 0];
      else {
        p = trie[p][Currbit ? 0 : 1];
        ans |= 1 << i;
      }
    }
 
    System.out.println(ans);
  }
 
  public static void main(String[] args) {
    // Initialising the trie
    Insert(0, 0);
 
    // Calling the Query
    MinXor(curx);
    Insert(7, curx);
    MinXor(curx);
    XorQuery(4);
    XorQuery(8);
    XorQuery(3);
    Insert(10, curx);
    Insert(3, curx);
    MinXor(curx);
    XorQuery(1);
  }
}
 
//This code is contributed by Potta Lokesh




# Python3 program to operate
# queries in a given set
 
Maxbits = 30
 
# Function for Query 1
 
 
def Insert(x, curx, trie):
    global sz
    # XOR each element before
    # storing it in the trie.
    x = x ^ curx
    p = 0
 
    # Storing xored element in the trie.
    for i in range(Maxbits - 1, -1, -1):
        if not(trie[p][x >> i & 1]):
            trie[p][x >> i & 1] = sz
            sz += 1
 
        p = trie[p][x >> i & 1]
 
 
# Function for Query 2
def XorQuery(x,):
    global curx
    # Simply xor-ing all the number which
    # was asked to xor with the set elements.
    curx ^= x
 
 
# Function for Query 3
def MinXor(x, trie):
    ans = 0
    p = 0
 
    # Finding the minimum element by checking
    # if x[i] bit is same with trie element.
    for i in range(Maxbits - 1, -1, -1):
        Currbit = (x >> i & 1)
 
        if (trie[p][Currbit]):
            p = trie[p][Currbit]
 
        else:
            p = trie[p][~Currbit]
            ans |= 1 << i
 
    print(ans)
 
 
# Driver code
if __name__ == '__main__':
    sz = 1
    curx = 0
    trie = [[0]*2 for _ in range(100)]
 
    # Initialising the trie
    Insert(0, 0, trie)
 
    # Calling the Query
    MinXor(curx, trie)
    Insert(7, curx, trie)
    MinXor(curx, trie)
    XorQuery(4, )
    XorQuery(8, )
    XorQuery(3, )
    Insert(10, curx, trie)
    Insert(3, curx,  trie)
    MinXor(curx, trie)
    XorQuery(1,)




// C# code for the above approach
using System;
 
class GFG{
static int Maxbits = 30;
static int sz = 1;
static int curx = 0;
static int[,] trie = new int[100,2];
 
// Function for Query 1
static void Insert(int x, int curx)
{
   
    // XOR each element before
    // storing it in the trie.
    x = x ^ curx;
    int p = 0;
 
    // Storing xored element in the trie.
    for (int i = Maxbits - 1; i >= 0; i--) {
    if (trie[p,x >> i & 1] == 0)
        trie[p,x >> i & 1] = sz++;
 
    p = trie[p,x >> i & 1];
    }
}
 
// Function for Query 2
static void XorQuery(int x) {
    // Simply xor-ing all the number which
    // was asked to xor with the set elements.
    curx = curx ^ x;
}
 
// Function for Query 3
static void MinXor(int x) {
    int ans = 0, p = 0;
 
    // Finding the minimum element by checking
    // if x[i] bit is same with trie element.
    for (int i = Maxbits - 1; i >= 0; i--) {
    bool Currbit = (x >> i & 1) == 1;
 
    if (trie[p,Currbit ? 1 : 0] != 0)
        p = trie[p,Currbit ? 1 : 0];
    else {
        p = trie[p,Currbit ? 0 : 1];
        ans |= 1 << i;
    }
    }
 
    Console.WriteLine(ans);
}
 
public static void Main() {
    // Initialising the trie
    Insert(0, 0);
 
    // Calling the Query
    MinXor(curx);
    Insert(7, curx);
    MinXor(curx);
    XorQuery(4);
    XorQuery(8);
    XorQuery(3);
    Insert(10, curx);
    Insert(3, curx);
    MinXor(curx);
    XorQuery(1);
}
}
 
// This code is contributed by Aman Kumar




<script>
    //Javascript code for the above approach
     
    const Maxbits = 30;
    let sz = 1;
    let curx = 0;
    const trie = new Array(100).fill().map(() => new Array(2).fill(0));
     
    // Function for Query 1
    function Insert(x, curx) {
        // XOR each element before storing it in the trie.
        x = x ^ curx;
        let p = 0;
     
        // Storing xored element in the trie.
        for (let i = Maxbits - 1; i >= 0; i--) {
            if (trie[p][(x >> i) & 1] == 0)
                trie[p][(x >> i) & 1] = sz++;
     
            p = trie[p][(x >> i) & 1];
        }
    }
     
    // Function for Query 2
    function XorQuery(x) {
        // Simply xor-ing all the number which
        // was asked to xor with the set elements.
        curx = curx ^ x;
    }
     
    // Function for Query 3
    function MinXor(x) {
        let ans = 0, p = 0;
     
        // Finding the minimum element by checking
        // if x[i] bit is same with trie element.
        for (let i = Maxbits - 1; i >= 0; i--) {
            let Currbit = (x >> i) & 1;
     
            if (trie[p][Currbit ? 1 : 0] != 0)
                p = trie[p][Currbit ? 1 : 0];
            else {
                p = trie[p][Currbit ? 0 : 1];
                ans |= 1 << i;
            }
        }
     
        document.write(ans);
    }
     
    // Driver code
    Insert(0, 0);
     
    // Calling the Query
    MinXor(curx);
    Insert(7, curx);
    MinXor(curx);
    XorQuery(4);
    XorQuery(8);
    XorQuery(3);
    Insert(10, curx);
    Insert(3, curx);
    MinXor(curx);
    XorQuery(1);
     
    // This code is contributed by Utkarsh Kumar.
      
</script>

Output: 
0
0
3

 

Time Complexity: O(N) per query. Where N is the number of bits in the query element.
Auxiliary Space: O(N) 


Article Tags :