Tuesday, November 19, 2024
Google search engine
HomeData Modelling & AIXOR of elements in a given range with updates using Fenwick Tree

XOR of elements in a given range with updates using Fenwick Tree

Given an array A[] of integers and array Q consisting of queries of the following two types:

  • (1, L, R) : Return XOR of all elements present between indices L and R.
  • (2, I, val) : update A[I] to A[I] XOR val.

The task is to solve each query and print the XOR for every Query of 1st type, using Fenwick Tree.
Examples:

Input: A[] = {2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9} 
Q = {{ 1, 3, 8}, {2, 4, 6}, {1, 3, 8}} 
Output : 
XOR of elements in range 3 to 8 is 5 
XOR of elements in range 3 to 8 is 3 
Explanation: 
XOR of subarray { 3, 2, 3, 4, 5, 6 } is 5. 
After 2nd query arr[4] gets replaced by 4. 
Xor of subarray { 3, 4, 3, 4, 5, 6 } is 3.
Input :A[] = {2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9} 
Q = {{1, 0, 9}, {2, 3, 6}, {2, 5, 5}, {2, 8, 1}, {1, 0, 9}} 
Output : 
XOR of elements in range 0 to 9 is 0 
XOR of elements in range 0 to 9 is 2

Approach:

  • For the query of type 1, return the Xor of elements in range [1, R] and range[1, L-1] using getXor().
  • In getXor(), For i starting from index to all its ancestors till 1, keep calculating XOR with BITree[i]. In order to get ancestor of i-th index in getXor() view, we just need to subtract LSB(least Significant Bit) from i by i = i – i&(-i). Finally return the final XOR value.
  • For query of type 2, update A[index] to A[index] ^ val. Update all ranges that include this element in BITree[] by calling updateBIT().
  • In updateBIT(), For every i starting from index to all its ancestors up to N, update BITree[i] as BITree[i] ^ val. In order to get ancestor of i-th index in updateBit() view, we just need to add LSB(least Significant Bit) from i by i = i + i&(-i).

Below is the implementation of the above approach:

C++




// C++ Program to find XOR of
// elements in given range [L, R].
 
#include <bits/stdc++.h>
using namespace std;
 
// Returns XOR of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// XORs of array elements are stored
// in BITree[].
int getXOR(int BITree[], int index)
{
    int ans = 0;
    index += 1;
 
    // Traverse ancestors
    // of BITree[index]
    while (index > 0) {
 
        // XOR current element
        // of BIT to ans
        ans ^= BITree[index];
 
        // Update index to that
        // of the parent node in
        // getXor() view by
        // subtracting LSB(Least
        // Significant Bit)
        index -= index & (-index);
    }
    return ans;
}
 
// Updates the Binary Index Tree by
// replacing all ancestors of index
// by their respective XOR with val
void updateBIT(int BITree[], int n,
               int index, int val)
{
    index = index + 1;
 
    // Traverse all ancestors
    // and XOR with 'val'.
    while (index <= n) {
 
        // XOR 'val' to current
        // node of BIT
        BITree[index] ^= val;
 
        // Update index to that
        // of the parent node in
        // updateBit() view by
        // adding LSB(Least
        // Significant Bit)
        index += index & (-index);
    }
}
 
// Constructs and returns a Binary
// Indexed Tree for the given array
int* constructBITree(int arr[], int n)
{
    // Create and initialize
    // the Binary Indexed Tree
    int* BITree = new int[n + 1];
    for (int i = 1; i <= n; i++)
        BITree[i] = 0;
 
    // Store the actual values in
    // BITree[] using update()
    for (int i = 0; i < n; i++)
        updateBIT(BITree, n, i, arr[i]);
 
    return BITree;
}
 
int rangeXor(int BITree[], int l, int r)
{
    return getXOR(BITree, r)
           ^ getXOR(BITree, l - 1);
}
 
// Driver Code
int main()
{
    int A[] = { 2, 1, 1, 3, 2, 3,
                4, 5, 6, 7, 8, 9 };
    int n = sizeof(A) / sizeof(A[0]);
 
    vector<vector<int> > q
        = { { 1, 0, 9 },
            { 2, 3, 6 },
            { 2, 5, 5 },
            { 2, 8, 1 },
            { 1, 0, 9 } };
 
    // Create the Binary Indexed Tree
    int* BITree = constructBITree(A, n);
 
    // Solve each query in Q
    for (int i = 0; i < q.size(); i++) {
        int id = q[i][0];
 
        if (id == 1) {
            int L = q[i][1];
            int R = q[i][2];
            cout << "XOR of elements "
                 << "in given range is "
                 << rangeXor(BITree, L, R)
                 << "\n";
        }
        else {
            int idx = q[i][1];
            int val = q[i][2];
            A[idx] ^= val;
 
            // Update the values of all
            // ancestors of idx
            updateBIT(BITree, n, idx, val);
        }
    }
 
    return 0;
}


Java




// Java Program to find XOR of
// elements in given range [L, R].
import java.util.*;
 
class GFG{
 
// Returns XOR of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// XORs of array elements are stored
// in BITree[].
static int getXOR(int BITree[], int index)
{
    int ans = 0;
    index += 1;
 
    // Traverse ancestors
    // of BITree[index]
    while (index > 0)
    {
 
        // XOR current element
        // of BIT to ans
        ans ^= BITree[index];
 
        // Update index to that
        // of the parent node in
        // getXor() view by
        // subtracting LSB(Least
        // Significant Bit)
        index -= index & (-index);
    }
    return ans;
}
 
// Updates the Binary Index Tree by
// replacing all ancestors of index
// by their respective XOR with val
static void updateBIT(int BITree[], int n,
                      int index, int val)
{
    index = index + 1;
 
    // Traverse all ancestors
    // and XOR with 'val'.
    while (index <= n)
    {
 
        // XOR 'val' to current
        // node of BIT
        BITree[index] ^= val;
 
        // Update index to that
        // of the parent node in
        // updateBit() view by
        // adding LSB(Least
        // Significant Bit)
        index += index & (-index);
    }
}
 
// Constructs and returns a Binary
// Indexed Tree for the given array
static int[] constructBITree(int arr[], int n)
{
    // Create and initialize
    // the Binary Indexed Tree
    int []BITree = new int[n + 1];
    for (int i = 1; i <= n; i++)
        BITree[i] = 0;
 
    // Store the actual values in
    // BITree[] using update()
    for (int i = 0; i < n; i++)
        updateBIT(BITree, n, i, arr[i]);
 
    return BITree;
}
 
static int rangeXor(int BITree[], int l, int r)
{
    return getXOR(BITree, r) ^
           getXOR(BITree, l - 1);
}
 
// Driver Code
public static void main(String[] args)
{
    int A[] = { 2, 1, 1, 3, 2, 3,
                4, 5, 6, 7, 8, 9 };
    int n = A.length;
 
    int [][]q = { { 1, 0, 9 },
                  { 2, 3, 6 },
                  { 2, 5, 5 },
                  { 2, 8, 1 },
                  { 1, 0, 9 } };
 
    // Create the Binary Indexed Tree
    int []BITree = constructBITree(A, n);
 
    // Solve each query in Q
    for (int i = 0; i < q.length; i++)
    {
        int id = q[i][0];
 
        if (id == 1)
        {
            int L = q[i][1];
            int R = q[i][2];
            System.out.print("XOR of elements " +
                           "in given range is " +
                         rangeXor(BITree, L, R) + "\n");
        }
        else
        {
            int idx = q[i][1];
            int val = q[i][2];
            A[idx] ^= val;
 
            // Update the values of all
            // ancestors of idx
            updateBIT(BITree, n, idx, val);
        }
    }
}
}
 
// This code is contributed by Princi Singh


Python3




# Python3 program to find XOR of
# elements in given range [L, R].
 
# Returns XOR of arr[0..index].
# This function assumes that the
# array is preprocessed and partial
# XORs of array elements are stored
# in BITree[].
def getXOR(BITree, index):
 
    ans = 0
    index += 1
 
    # Traverse ancestors
    # of BITree[index]
    while (index > 0):
     
        # XOR current element
        # of BIT to ans
        ans ^= BITree[index]
 
        # Update index to that
        # of the parent node in
        # getXor() view by
        # subtracting LSB(Least
        # Significant Bit)
        index -= index & (-index)
     
    return ans
 
# Updates the Binary Index Tree by
# replacing all ancestors of index
# by their respective XOR with val
def updateBIT(BITree, n, index, val):
 
    index = index + 1
 
    # Traverse all ancestors
    # and XOR with 'val'.
    while (index <= n):
     
        # XOR 'val' to current
        # node of BIT
        BITree[index] ^= val
 
        # Update index to that
        # of the parent node in
        # updateBit() view by
        # adding LSB(Least
        # Significant Bit)
        index += index & (-index)
     
# Constructs and returns a Binary
# Indexed Tree for the given array
def constructBITree(arr, n):
 
    # Create and initialize
    # the Binary Indexed Tree
    BITree = [0] * (n + 1)
     
    # Store the actual values in
    # BITree[] using update()
    for i in range(n):
        updateBIT(BITree, n, i, arr[i])
 
    return BITree
 
def rangeXor(BITree, l, r):
 
    return (getXOR(BITree, r) ^
            getXOR(BITree, l - 1))
            
# Driver Code
if __name__ == "__main__":
     
    A = [ 2, 1, 1, 3, 2, 3,
          4, 5, 6, 7, 8, 9 ]
    n = len(A)
 
    q = [ [ 1, 0, 9 ], [ 2, 3, 6 ],
          [ 2, 5, 5 ], [ 2, 8, 1 ],
          [ 1, 0, 9 ] ]
 
    # Create the Binary Indexed Tree
    BITree = constructBITree(A, n)
 
    # Solve each query in Q
    for i in range(len(q)):
        id = q[i][0]
 
        if (id == 1):
            L = q[i][1]
            R = q[i][2]
            print("XOR of elements in "
                  "given range is ",
                  rangeXor(BITree, L, R))
        else:
            idx = q[i][1]
            val = q[i][2]
            A[idx] ^= val
 
            # Update the values of all
            # ancestors of idx
            updateBIT(BITree, n, idx, val)
 
# This code is contributed by jana_sayantan


C#




// C# program to find XOR of
// elements in given range [L, R].
using System;
 
class GFG{
 
// Returns XOR of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// XORs of array elements are stored
// in BITree[].
static int getXOR(int []BITree, int index)
{
    int ans = 0;
    index += 1;
 
    // Traverse ancestors
    // of BITree[index]
    while (index > 0)
    {
 
        // XOR current element
        // of BIT to ans
        ans ^= BITree[index];
 
        // Update index to that
        // of the parent node in
        // getXor() view by
        // subtracting LSB(Least
        // Significant Bit)
        index -= index & (-index);
    }
    return ans;
}
 
// Updates the Binary Index Tree by
// replacing all ancestors of index
// by their respective XOR with val
static void updateBIT(int []BITree, int n,
                      int index, int val)
{
    index = index + 1;
 
    // Traverse all ancestors
    // and XOR with 'val'.
    while (index <= n)
    {
 
        // XOR 'val' to current
        // node of BIT
        BITree[index] ^= val;
 
        // Update index to that
        // of the parent node in
        // updateBit() view by
        // adding LSB(Least
        // Significant Bit)
        index += index & (-index);
    }
}
 
// Constructs and returns a Binary
// Indexed Tree for the given array
static int[] constructBITree(int []arr,
                             int n)
{
     
    // Create and initialize
    // the Binary Indexed Tree
    int []BITree = new int[n + 1];
    for(int i = 1; i <= n; i++)
       BITree[i] = 0;
 
    // Store the actual values in
    // BITree[] using update()
    for(int i = 0; i < n; i++)
       updateBIT(BITree, n, i, arr[i]);
 
    return BITree;
}
 
static int rangeXor(int []BITree, int l,
                                  int r)
{
    return getXOR(BITree, r) ^
           getXOR(BITree, l - 1);
}
 
// Driver Code
public static void Main(String[] args)
{
    int []A = { 2, 1, 1, 3, 2, 3,
                4, 5, 6, 7, 8, 9 };
    int n = A.Length;
     
    int [,]q = { { 1, 0, 9 },
                 { 2, 3, 6 },
                 { 2, 5, 5 },
                 { 2, 8, 1 },
                 { 1, 0, 9 } };
 
    // Create the Binary Indexed Tree
    int []BITree = constructBITree(A, n);
 
    // Solve each query in Q
    for(int i = 0; i < q.GetLength(0); i++)
    {
       int id = q[i, 0];
        
       if (id == 1)
       {
           int L = q[i, 1];
           int R = q[i, 2];
           Console.Write("XOR of elements " +
                       "in given range is " +
                     rangeXor(BITree, L, R) + "\n");
       }
       else
       {
           int idx = q[i, 1];
           int val = q[i, 2];
           A[idx] ^= val;
            
           // Update the values of
           // all ancestors of idx
           updateBIT(BITree, n, idx, val);
       }
    }
}
}
 
// This code is contributed by sapnasingh4991


Javascript




<script>
 
// Javascript Program to find XOR of
// elements in given range [L, R].
 
// Returns XOR of arr[0..index].
// This function assumes that the
// array is preprocessed and partial
// XORs of array elements are stored
// in BITree[].
function getXOR(BITree, index)
{
    let ans = 0;
    index += 1;
 
    // Traverse ancestors
    // of BITree[index]
    while (index > 0) {
 
        // XOR current element
        // of BIT to ans
        ans ^= BITree[index];
 
        // Update index to that
        // of the parent node in
        // getXor() view by
        // subtracting LSB(Least
        // Significant Bit)
        index -= index & (-index);
    }
    return ans;
}
 
// Updates the Binary Index Tree by
// replacing all ancestors of index
// by their respective XOR with val
function updateBIT(BITree, n, index, val)
{
    index = index + 1;
 
    // Traverse all ancestors
    // and XOR with 'val'.
    while (index <= n) {
 
        // XOR 'val' to current
        // node of BIT
        BITree[index] ^= val;
 
        // Update index to that
        // of the parent node in
        // updateBit() view by
        // adding LSB(Least
        // Significant Bit)
        index += index & (-index);
    }
}
 
// Constructs and returns a Binary
// Indexed Tree for the given array
function constructBITree(arr, n)
{
    // Create and initialize
    // the Binary Indexed Tree
    let BITree = new Array(n + 1);
    for (let i = 1; i <= n; i++)
        BITree[i] = 0;
 
    // Store the actual values in
    // BITree[] using update()
    for (let i = 0; i < n; i++)
        updateBIT(BITree, n, i, arr[i]);
 
    return BITree;
}
 
function rangeXor(BITree, l, r)
{
    return getXOR(BITree, r)
           ^ getXOR(BITree, l - 1);
}
 
// Driver Code
    let A = [ 2, 1, 1, 3, 2, 3,
                4, 5, 6, 7, 8, 9 ];
    let n = A.length;
 
    let q
        = [ [ 1, 0, 9 ],
            [ 2, 3, 6 ],
            [ 2, 5, 5 ],
            [ 2, 8, 1 ],
            [ 1, 0, 9 ] ];
 
    // Create the Binary Indexed Tree
    let BITree = constructBITree(A, n);
 
    // Solve each query in Q
    for (let i = 0; i < q.length; i++) {
        let id = q[i][0];
 
        if (id == 1) {
            let L = q[i][1];
            let R = q[i][2];
            document.write("XOR of elements "
                 + "in given range is "
                 + rangeXor(BITree, L, R)
                 + "<br>");
        }
        else {
            let idx = q[i][1];
            let val = q[i][2];
            A[idx] ^= val;
 
            // Update the values of all
            // ancestors of idx
            updateBIT(BITree, n, idx, val);
        }
    }
 
</script>


Output: 

XOR of elements in given range is 0
XOR of elements in given range is 2

Time complexity of getXor(): O(log N) 
Time complexity of updateBIT(): O(log N) 
Overall Time complexity: O(M * log N) where M and N are the number of queries and size of the given array respectively.
Auxiliary Space: O(N)

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments