<p>You are given two <strong>0-indexed</strong> arrays <code>nums1</code> and <code>nums2</code> and a 2D array <code>queries</code> of queries. There are three types of queries:</p>

<ol>
	<li>For a query of type 1, <code>queries[i]&nbsp;= [1, l, r]</code>. Flip the values from <code>0</code> to <code>1</code> and from <code>1</code> to <code>0</code> in <code>nums1</code>&nbsp;from index <code>l</code> to index <code>r</code>. Both <code>l</code> and <code>r</code> are <strong>0-indexed</strong>.</li>
	<li>For a query of type 2, <code>queries[i]&nbsp;= [2, p, 0]</code>. For every index <code>0 &lt;= i &lt; n</code>, set&nbsp;<code>nums2[i] =&nbsp;nums2[i]&nbsp;+ nums1[i]&nbsp;* p</code>.</li>
	<li>For a query of type 3, <code>queries[i]&nbsp;= [3, 0, 0]</code>. Find the sum of the elements in <code>nums2</code>.</li>
</ol>

<p>Return <em>an array containing all the answers to the third type&nbsp;queries.</em></p>

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

<pre>
<strong>Input:</strong> nums1 = [1,0,1], nums2 = [0,0,0], queries = [[1,1,1],[2,1,0],[3,0,0]]
<strong>Output:</strong> [3]
<strong>Explanation:</strong> After the first query nums1 becomes [1,1,1]. After the second query, nums2 becomes [1,1,1], so the answer to the third query is 3. Thus, [3] is returned.
</pre>

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

<pre>
<strong>Input:</strong> nums1 = [1], nums2 = [5], queries = [[2,0,0],[3,0,0]]
<strong>Output:</strong> [5]
<strong>Explanation:</strong> After the first query, nums2 remains [5], so the answer to the second query is 5. Thus, [5] is returned.
</pre>

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

<ul>
	<li><code>1 &lt;= nums1.length,nums2.length &lt;= 10<sup>5</sup></code></li>
	<li><code>nums1.length = nums2.length</code></li>
	<li><code>1 &lt;= queries.length &lt;= 10<sup>5</sup></code></li>
	<li><code><font face="monospace">queries[i].length = 3</font></code></li>
	<li><code><font face="monospace">0 &lt;= l &lt;= r &lt;= nums1.length - 1</font></code></li>
	<li><code><font face="monospace">0 &lt;= p &lt;= 10<sup>6</sup></font></code></li>
	<li><code>0 &lt;= nums1[i] &lt;= 1</code></li>
	<li><code>0 &lt;= nums2[i] &lt;= 10<sup>9</sup></code></li>
</ul>

class Solution:
    def handleQuery(self, nums1, nums2, queries):
        n = len(nums1)
        m = len(queries)
        segment_tree = [0] * (4 * n)
        lazy = [False] * (4 * n)
        sum_nums2 = sum(nums2)
        result = []

        def build_segment_tree(node, start, end):
            if start == end:
                segment_tree[node] = nums1[start]
            else:
                mid = (start + end) // 2
                left_child = 2 * node + 1
                right_child = 2 * node + 2
                build_segment_tree(left_child, start, mid)
                build_segment_tree(right_child, mid + 1, end)
                segment_tree[node] = segment_tree[left_child] + segment_tree[right_child]

        def update_segment_tree(node, start, end, l, r):
            if lazy[node]:
                segment_tree[node] = (end - start + 1) - segment_tree[node]
                if start != end:
                    lazy[2 * node + 1] = not lazy[2 * node + 1]
                    lazy[2 * node + 2] = not lazy[2 * node + 2]
                lazy[node] = False

            if start > end or start > r or end < l:
                return

            if l <= start and end <= r:
                segment_tree[node] = (end - start + 1) - segment_tree[node]
                if start != end:
                    lazy[2 * node + 1] = not lazy[2 * node + 1]
                    lazy[2 * node + 2] = not lazy[2 * node + 2]
                return

            mid = (start + end) // 2
            update_segment_tree(2 * node + 1, start, mid, l, r)
            update_segment_tree(2 * node + 2, mid + 1, end, l, r)
            segment_tree[node] = segment_tree[2 * node + 1] + segment_tree[2 * node + 2]

        def query_segment_tree(node, start, end, l, r):
            if start > end or start > r or end < l:
                return 0

            if lazy[node]:
                segment_tree[node] = (end - start + 1) - segment_tree[node]
                if start != end:
                    lazy[2 * node + 1] = not lazy[2 * node + 1]
                    lazy[2 * node + 2] = not lazy[2 * node + 2]
                lazy[node] = False

            if l <= start and end <= r:
                return segment_tree[node]

            mid = (start + end) // 2
            left_sum = query_segment_tree(2 * node + 1, start, mid, l, r)
            right_sum = query_segment_tree(2 * node + 2, mid + 1, end, l, r)
            return left_sum + right_sum

        build_segment_tree(0, 0, n - 1)

        for query in queries:
            if query[0] == 1:
                _, l, r = query
                update_segment_tree(0, 0, n - 1, l, r)
            elif query[0] == 2:
                _, p, _ = query
                sum_nums2 += p * query_segment_tree(0, 0, n - 1, 0, n - 1)
            else:
                result.append(sum_nums2)

        return result
55100