algorithmxorsegment-treebitwise-xor

XOR queries on a given array


Given an array of n integers, indexed from 1->n. The task is to perform of Q given queries, and print the sum of the array after each queries.

We can perform three types of operations:

Example:

Input

arr[] = {2, 3, 9, 5, 6, 6}, Q = 5
1 3
3 5
2 2
3 2
2 7

Output: 34 37 31 27 23

Explanation:

1 3 -> arr[] = {2, 3, 9, 5, 6, 6, 3} -> sum = 34

3 5 -> arr[] = {7, 6, 12, 0, 3, 3, 6} -> sum = 37

2 2 -> arr[] = {7, 12, 0, 3, 3, 6} -> sum = 31

3 2 -> arr[] = {5, 14, 2, 1, 1, 4} -> sum = 27

2 7 -> arr[] = {5, 14, 2, 1, 1} -> sum = 23

P/S: I'm trying to solve the problem with Segment Tree, but I can't update the tree with XOR operator. Is there any other way to solve this problem? I'm trying to solve it in O(n.logn)


Solution

  • Assuming your numbers do not exceed some standard constant like 232 or 264, we can do this in constant time, by counting the bits separately.

    You will need to:

    1. Remember how many numbers there are in the array
    2. Remember how many lit bits there are at every position in the binary positioning system.

    So here's your example, expanded into bits, with the least significant ones at the top:

    2  3  9  5  6  6  3 | sum
    -------------------------
    0  1  1  1  0  0  1 | 4
    1  1  0  0  1  1  1 | 5
    0  0  0  1  1  1  0 | 3
    0  0  1  0  0  0  0 | 1
    

    Now, that means that there are

    We now xor this with 5, which is 0101 in binary, so there will now be

    If we sum this up, we get 3 * 2^0 + 5 * 2^1 + 4 * 2^2 + 1 * 2^3 = 37 (where now by ^ I mean exponentiation as opposed to xor).

    So this is what you do every time the xor operation pops up. Adding and removing numbers is the easy parts because you go over their bits and accordingly adjust the counts of lit "i-th" bits in the array.