LeetCode 2569. Handling Sum Queries After Update Solution in Java, C++, Python & Go | Explanation + Code

CoderIndeed
0
2569. Handling Sum Queries After Update

Description

You are given two 0-indexed arrays nums1 and nums2 and a 2D array queries of queries. There are three types of queries:

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

Return an array containing all the answers to the third type queries.

 

Example 1:

Input: nums1 = [1,0,1], nums2 = [0,0,0], queries = [[1,1,1],[2,1,0],[3,0,0]]
Output: [3]
Explanation: 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.

Example 2:

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

 

Constraints:

  • 1 <= nums1.length,nums2.length <= 105
  • nums1.length = nums2.length
  • 1 <= queries.length <= 105
  • queries[i].length = 3
  • 0 <= l <= r <= nums1.length - 1
  • 0 <= p <= 106
  • 0 <= nums1[i] <= 1
  • 0 <= nums2[i] <= 109

Solutions

Solution 1: Segment Tree

According to the problem description:

  • Operation 1 is to reverse all numbers in the index range [l,..r] of array nums1, that is, change 0 to 1 and 1 to 0.
  • Operation 3 is to sum all numbers in array nums2.
  • Operation 2 is to add the sum of all numbers in array nums2 with p times the sum of all numbers in array nums1, that is, sum(nums2) = sum(nums2) + p * sum(nums1).

Therefore, we actually only need to maintain the segment sum of array nums1, which can be implemented through a segment tree.

We define each node of the segment tree as Node, each node contains the following attributes:

  • l: The left endpoint of the node, the index starts from 1.
  • r: The right endpoint of the node, the index starts from 1.
  • s: The segment sum of the node.
  • lazy: The lazy tag of the node.

The segment tree mainly has the following operations:

  • build(u, l, r): Build the segment tree.
  • pushdown(u): Propagate the lazy tag.
  • pushup(u): Update the information of the parent node with the information of the child nodes.
  • modify(u, l, r): Modify the segment sum. In this problem, it is to reverse each number in the segment, so the segment sum s = r - l + 1 - s.
  • query(u, l, r): Query the segment sum.

First, calculate the sum of all numbers in array nums2, denoted as s.

When executing operation 1, we only need to call modify(1, l + 1, r + 1).

When executing operation 2, we update s = s + p × query(1, 1, n).

When executing operation 3, we just need to add s to the answer array.

The time complexity is O(n + m × log n), and the space complexity is O(n). Where n and m are the lengths of arrays nums1 and queries respectively.

PythonJavaC++Go
class Node: def __init__(self): self.l = self.r = 0 self.s = self.lazy = 0 class SegmentTree: def __init__(self, nums): self.nums = nums n = len(nums) self.tr = [Node() for _ in range(n << 2)] self.build(1, 1, n) def build(self, u, l, r): self.tr[u].l, self.tr[u].r = l, r if l == r: self.tr[u].s = self.nums[l - 1] return mid = (l + r) >> 1 self.build(u << 1, l, mid) self.build(u << 1 | 1, mid + 1, r) self.pushup(u) def modify(self, u, l, r): if self.tr[u].l >= l and self.tr[u].r <= r: self.tr[u].lazy ^= 1 self.tr[u].s = self.tr[u].r - self.tr[u].l + 1 - self.tr[u].s return self.pushdown(u) mid = (self.tr[u].l + self.tr[u].r) >> 1 if l <= mid: self.modify(u << 1, l, r) if r > mid: self.modify(u << 1 | 1, l, r) self.pushup(u) def query(self, u, l, r): if self.tr[u].l >= l and self.tr[u].r <= r: return self.tr[u].s self.pushdown(u) mid = (self.tr[u].l + self.tr[u].r) >> 1 res = 0 if l <= mid: res += self.query(u << 1, l, r) if r > mid: res += self.query(u << 1 | 1, l, r) return res def pushup(self, u): self.tr[u].s = self.tr[u << 1].s + self.tr[u << 1 | 1].s def pushdown(self, u): if self.tr[u].lazy: mid = (self.tr[u].l + self.tr[u].r) >> 1 self.tr[u << 1].s = mid - self.tr[u].l + 1 - self.tr[u << 1].s self.tr[u << 1].lazy ^= 1 self.tr[u << 1 | 1].s = self.tr[u].r - mid - self.tr[u << 1 | 1].s self.tr[u << 1 | 1].lazy ^= 1 self.tr[u].lazy ^= 1 class Solution: def handleQuery( self, nums1: List[int], nums2: List[int], queries: List[List[int]] ) -> List[int]: tree = SegmentTree(nums1) s = sum(nums2) ans = [] for op, a, b in queries: if op == 1: tree.modify(1, a + 1, b + 1) elif op == 2: s += a * tree.query(1, 1, len(nums1)) else: ans.append(s) return ans(code-box)

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !