1310-xor-queries-of-a-subarray

Try it on leetcode

Description

You are given an array arr of positive integers. You are also given the array queries where queries[i] = [lefti, righti].

For each query i compute the XOR of elements from lefti to righti (that is, arr[lefti] XOR arr[lefti + 1] XOR ... XOR arr[righti] ).

Return an array answer where answer[i] is the answer to the ith query.

 

Example 1:

Input: arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
Output: [2,7,14,8] 
Explanation: 
The binary representation of the elements in the array are:
1 = 0001 
3 = 0011 
4 = 0100 
8 = 1000 
The XOR values for queries are:
[0,1] = 1 xor 3 = 2 
[1,2] = 3 xor 4 = 7 
[0,3] = 1 xor 3 xor 4 xor 8 = 14 
[3,3] = 8

Example 2:

Input: arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]]
Output: [8,0,4,4]

 

Constraints:

  • 1 <= arr.length, queries.length <= 3 * 104
  • 1 <= arr[i] <= 109
  • queries[i].length == 2
  • 0 <= lefti <= righti < arr.length

Solution(Python)

class segmentTree:
    def __init__(self, arr, n):
        self.n = n
        self.tree = [0] * ((4 * n) + 1)
        self.build(arr, 1, 0, n - 1)

    def build(self, arr, v, lt, rt):
        if lt == rt:
            self.tree[v] = arr[lt]
        else:
            mt = (lt + rt) >> 1
            self.build(arr, 2 * v, lt, mt)
            self.build(arr, 2 * v + 1, mt + 1, rt)
            self.tree[v] = self.tree[2 * v] ^ self.tree[2 * v + 1]

    def query(self, l, r):
        return self.__query(1, 0, self.n - 1, l, r)

    def __query(self, v, lt, rt, l, r):
        if l > r:
            return 0
        if l == lt and r == rt:
            return self.tree[v]
        mt = (lt + rt) >> 1
        return self.__query(2 * v, lt, mt, l, min(mt, r)) ^ self.__query(
            2 * v + 1, mt + 1, rt, max(mt + 1, l), r
        )


class Solution:
    def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
        return self.sTree(arr, queries)

    # Time Complexoty: O(n)
    # space Complexity: O(n)
    def prexor(self, arr: List[int], queries: List[List[int]]) -> List[int]:
        n = len(arr)
        if not n:
            return []
        prefXOR = [0] * n
        prefXOR[0] = arr[0]
        for i in range(1, n):
            prefXOR[i] = prefXOR[i - 1] ^ arr[i]
        res = []
        for l, r in queries:
            if l > 0:
                res.append(prefXOR[l - 1] ^ prefXOR[r])
            else:
                res.append(prefXOR[r])
        return res

    # Time Complexoty: O(n)
    # space Complexity: O(n)
    def sTree(self, arr: List[int], queries: List[List[int]]) -> List[int]:
        n = len(arr)
        st = segmentTree(arr, n)
        return [st.query(l, r) for l, r in queries]