📌  相关文章
📜  使用Fenwick树从前缀求和数组中查找K的下界并进行更新(1)

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

使用Fenwick树从前缀求和数组中查找K的下界并进行更新

简介

Fenwick树,也称为树状数组,是一种用于快速计算前缀和的数据结构。它允许在 $O(\log n)$ 的时间复杂度内实现单点修改和区间查询。本文将介绍如何使用Fenwick树从前缀求和数组中查找K的下界并进行更新,以及优化技巧和注意事项。

思路

在前缀和数组中查找K的下界,即查找第一个大于等于K的值所对应的下标。我们可以利用Fenwick树的区间查询功能,找到第一个大于等于K的前缀和对应的下标。

具体实现如下:

  1. 构建Fenwick树。
  2. 对前缀和数组进行二分查找,查找第一个大于等于K的前缀和值。
  3. 利用Fenwick树的区间查询功能,查找第一个大于等于查找得到的前缀和值的下标。
  4. 将该下标更新为K的值。
代码实现

以下为Python代码实现:

class FenwickTree:
    def __init__(self, n):
        self.n = n
        self.tree = [0] * (n+1)

    def update(self, i, x):
        while i <= self.n:
            self.tree[i] += x
            i += i & -i

    def query(self, i):
        res = 0
        while i > 0:
            res += self.tree[i]
            i -= i & -i
        return res

def lower_bound(fenwick, val):
    left, right = 1, fenwick.n
    while left < right:
        mid = (left + right) // 2
        if fenwick.query(mid) >= val:
            right = mid
        else:
            left = mid + 1
    return left

def update_k(nums, k):
    n = len(nums)
    fenwick = FenwickTree(n)
    for i in range(1, n+1):
        fenwick.update(i, nums[i-1])

    lb_idx = lower_bound(fenwick, k)
    nums[lb_idx-1] = k
    fenwick.update(lb_idx, k - fenwick.query(lb_idx-1))
优化技巧
  1. 构建Fenwick树时可以使用数组代替列表,可以提高程序运行效率。
  2. 在二分查找中,可以使用bisect模块的bisect_left函数代替手写二分查找,提高代码可读性。
注意事项
  1. Fenwick树的下标从1开始。
  2. 确保输入的前缀和数组满足单调性(例如升序或降序),否则无法得到正确的结果。
总结

本文介绍了如何使用Fenwick树从前缀和数组中查找K的下界并进行更新,讲解了其思路、代码实现、优化技巧和注意事项。Fenwick树是一种常用的数据结构,在算法竞赛和工程实践中广泛应用。