📌  相关文章
📜  将第一个或最后一个K元素乘以X后,计算数组的GCD的查询(1)

📅  最后修改于: 2023-12-03 15:09:38.687000             🧑  作者: Mango

将第一个或最后一个K元素乘以X后,计算数组的GCD的查询

介绍

给定一个整数数组和多个查询,每个查询都包含三个整数:k,x和t,要求将第一个或最后一个k元素乘以x,然后计算数组的GCD,并在t次查询后输出结果。

思路

我们可以使用线段树来解决这个问题。线段树是一种树形数据结构,通过分割区间并将其分配到每个节点下,来实现区间查询。在这个问题中,我们可以将数组分为若干个区间,每个区间代表一个节点,最后我们可以计算出数组的GCD,这正是我们所需要的答案。

具体地,我们可以使用线段树来维护一些信息。例如,我们可以在每个节点上维护区间内元素的最大公约数gcd,以及区间内k的个数cnt。对于一个查询,我们可以通过查询对应的节点来获得区间的信息,并在节点上修改cnt和gcd。

代码

首先,我们需要定义一个线段树的节点。节点包含4个变量:区间左右端点l和r,区间内元素最大公约数gcd,以及区间内k的个数cnt。

class Node:
    def __init__(self, l, r):
        self.l = l
        self.r = r
        self.gcd = None
        self.cnt = 0

接下来,我们可以定义一个函数来建立线段树。由于我们需要修改节点的信息,在递归上建立节点时,我们需要将节点传递到下一层的函数中。

def build_tree(nums, l, r):
    if l == r:
        return Node(l, r)
    mid = (l + r) // 2
    left = build_tree(nums, l, mid)
    right = build_tree(nums, mid+1, r)
    node = Node(l, r)
    node.gcd = math.gcd(left.gcd, right.gcd)
    return node

接着,我们定义一个函数来查询某个节点。我们首先需要检查当前节点是否包含k元素,如果包含,则将节点的cnt加1,同时更新gcd。如果当前节点不包含k元素,但是它的子节点中包含k元素,则需要从子节点中继承cnt和gcd。如果当前节点不包含k元素,且它的子节点中也不包含k元素,则无需更新。

def update(node, k, x):
    if node.l == node.r:
        if node.l == k:
            node.gcd *= x
        return
    if k <= (node.l+node.r)//2:
        update(node.left, k, x)
    else:
        update(node.right, k, x)
    node.cnt = node.left.cnt + node.right.cnt
    node.gcd = None
    if node.left.cnt > 0:
        node.gcd = node.left.gcd
    if node.right.cnt > 0:
        if node.gcd is None:
            node.gcd = node.right.gcd
        else:
            node.gcd = math.gcd(node.gcd, node.right.gcd)
    if node.gcd is None:
        node.gcd = 1

最后,我们定义一个函数来进行多次查询,并返回最终的结果。

def gcd_query(nums, queries):
    tree = build_tree(nums, 0, len(nums)-1)
    for k, x, t in queries:
        if k == 1:
            update(tree, 0, x)
        elif k == len(nums):
            update(tree, len(nums)-1, x)
        t -= 1
        while t > 0:
            t -= 1
            if tree.gcd == 1:
                break
            if tree.left.gcd % tree.gcd == 0:
                tree = tree.left
            else:
                tree = tree.right
        print(tree.gcd)
总结

本文介绍了一种利用线段树解决数组GCD查询问题的思路,同时给出了详细的代码实现。在解决其他问题时,我们也可以使用类似的方法来利用线段树来解决问题。在实现线段树时,需要特别注意节点信息的维护以及递归的方法。