📜  门| GATE-CS-2004 |问题 8(1)

📅  最后修改于: 2023-12-03 14:58:26.298000             🧑  作者: Mango

门 | GATE-CS-2004 |问题 8

这是一道计算机科学常见的问题,也是GATE-CS-2004考试的一道问题。

问题描述

给定一个n个元素的整数数组,和一组操作。操作中包括三种类型:

  1. 0 l r:查询l到r之间的元素乘积,输出结果。
  2. 1 i x:将第i个元素修改为x。
  3. 2 i x:将第i个元素乘以x。

假设数组中的元素都是正整数。

解法

这道问题可以使用线段树来解决。线段树是一种二叉树,每个节点代表数组中的一段区间。线段树的叶子节点对应数组中的元素,而非叶子节点代表的区间是它的子节点所代表区间的并集。

对于区间乘积的查询,可以在每个节点中存储区间的乘积。查询时,如果要查询的区间正好是当前节点所代表的区间,则直接返回当前节点所存储的乘积;否则递归查询它的子节点。

对于修改操作,可以通过递归找到对应的叶子节点,然后修改叶子节点对应的元素的值。然后从叶子节点开始逐层向上更新节点存储的区间乘积。

对于乘法修改操作,可以采用和修改操作类似的方式进行递归。具体实现中需要注意乘法修改操作的顺序。

代码片段

下面是使用Python实现线段树解决该问题的代码片段:

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

    def build(self, arr, node, left, right):
        if left == right:
            self.tree[node] = arr[left]
        else:
            mid = (left + right) // 2
            self.build(arr, node * 2, left, mid)
            self.build(arr, node * 2 + 1, mid + 1, right)
            self.tree[node] = self.tree[node * 2] * self.tree[node * 2 + 1]

    def query(self, node, left, right, qleft, qright):
        if qright < left or qleft > right:
            return 1
        elif qleft <= left and qright >= right:
            return self.tree[node]
        else:
            mid = (left + right) // 2
            return self.query(node * 2, left, mid, qleft, qright) * self.query(node * 2 + 1, mid + 1, right, qleft, qright)

    def update(self, node, left, right, index, value):
        if left == right:
            self.tree[node] = value
        else:
            mid = (left + right) // 2
            if index <= mid:
                self.update(node * 2, left, mid, index, value)
            else:
                self.update(node * 2 + 1, mid + 1, right, index, value)
            self.tree[node] = self.tree[node * 2] * self.tree[node * 2 + 1]

    def multiply(self, node, left, right, index, value):
        if left == right:
            self.tree[node] *= value
        else:
            mid = (left + right) // 2
            if index <= mid:
                self.multiply(node * 2, left, mid, index, value)
            else:
                self.multiply(node * 2 + 1, mid + 1, right, index, value)
            self.tree[node] = self.tree[node * 2] * self.tree[node * 2 + 1]

n = int(input())
arr = list(map(int, input().split()))

st = SegmentTree(arr)

q = int(input())
for i in range(q):
    query = list(map(int, input().split()))
    if query[0] == 0:
        l, r = query[1], query[2]
        print(st.query(1, 0, n - 1, l - 1, r - 1))
    elif query[0] == 1:
        i, x = query[1], query[2]
        st.update(1, 0, n - 1, i - 1, x)
    else:
        i, x = query[1], query[2]
        st.multiply(1, 0, n - 1, i - 1, x)

以上就是解决该问题的一个示例实现。