<p>You are given an array <code>arr</code> of positive integers. You are also given the array <code>queries</code> where <code>queries[i] = [left<sub>i, </sub>right<sub>i</sub>]</code>.</p>

<p>For each query <code>i</code> compute the <strong>XOR</strong> of elements from <code>left<sub>i</sub></code> to <code>right<sub>i</sub></code> (that is, <code>arr[left<sub>i</sub>] XOR arr[left<sub>i</sub> + 1] XOR ... XOR arr[right<sub>i</sub>]</code> ).</p>

<p>Return an array <code>answer</code> where <code>answer[i]</code> is the answer to the <code>i<sup>th</sup></code> query.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
<strong>Output:</strong> [2,7,14,8] 
<strong>Explanation:</strong> 
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
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]]
<strong>Output:</strong> [8,0,4,4]
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= arr.length, queries.length &lt;= 3 * 10<sup>4</sup></code></li>
	<li><code>1 &lt;= arr[i] &lt;= 10<sup>9</sup></code></li>
	<li><code>queries[i].length == 2</code></li>
	<li><code>0 &lt;= left<sub>i</sub> &lt;= right<sub>i</sub> &lt; arr.length</code></li>
</ul>


class SegmentTree {
   public:
    size_t depth;        // depth >= 1
    vector<int> buffer;  // 1-based buffer

    SegmentTree() {}
    void build(vector<int>& arr) {
        depth = ceil(log2(arr.size())) + 1;
        buffer = vector<int>(1 << depth, 0);

        // Fill leaf
        int offset = 1 << (depth - 1);
        for (int i = 0; i < (int)arr.size(); i++) {
            buffer[offset + i] = arr[i];
        }
        for (int i = (int)arr.size(); i < (1 << (depth - 1)); i++) {
            buffer[offset + i] = 0;
        }
        // Bottom up building
        for (int i = offset - 1; i >= 1; i--) {
            buffer[i] = buffer[i * 2] ^ buffer[i * 2 + 1];
        }
    }
    int query(int l, int r) {
        return recursive_query(1, 1, l, r);
    }
    int recursive_query(int i, int d, int l, int r) {
        int offset = 1 << (d - 1);
        int range = 1 << (depth - d);
        int bl = (i - offset) * range;
        int br = (i - offset + 1) * range - 1;
        if (r < bl || l > br)
            return 0;
        l = max(l, bl);
        r = min(r, br);
        if (l == bl && r == br) {
            // Matched
            return buffer[i];
        }
        int lval = recursive_query(i * 2, d + 1, l, r);
        int rval = recursive_query(i * 2 + 1, d + 1, l, r);
        return lval ^ rval;
    }
};

class Solution {
   public:
    vector<int> xorQueries(vector<int>& arr, vector<vector<int>>& queries) {
        SegmentTree segment_tree;
        segment_tree.build(arr);
        vector<int> result;
        for (auto& q : queries) {
            result.push_back(segment_tree.query(q[0], q[1]));
        }
        return result;
    }
};
42700