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 valvoid 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 arrayint* 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 Codeint 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 valstatic 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 arraystatic 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 Codepublic 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 valdef 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 arraydef 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 Codeif __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 valstatic 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 arraystatic 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 Codepublic 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 valfunction 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 arrayfunction 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> |
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)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

… [Trackback]
[…] Read More Information here to that Topic: geeksforgeeks.org/xor-of-elements-in-a-given-range-with-updates-using-fenwick-tree/ […]
… [Trackback]
[…] There you can find 56294 additional Information to that Topic: geeksforgeeks.org/xor-of-elements-in-a-given-range-with-updates-using-fenwick-tree/ […]
… [Trackback]
[…] Read More on that Topic: geeksforgeeks.org/xor-of-elements-in-a-given-range-with-updates-using-fenwick-tree/ […]