HOME

Fenwick树区间查询实现方法

Fenwick树(也称为Binary Indexed Tree)是一种高效的数据结构,用于处理大规模数组上的前缀和问题以及支持高效的单点更新操作。本文将详细介绍如何使用Fenwick树进行区间查询的操作。

1. 基本概念与初始化

首先,我们需要了解基本的概念和初始化步骤。

初始化时,将BIT数组的所有元素置为0,然后根据给定的初始值对数组进行更新操作。假设初始状态下的A[i] = a_i

def init(A, n):
    B = [0] * (n + 1)
    for i in range(1, n + 1):
        update(B, i, A[i - 1])

其中,update函数用于将数组A在索引i位置的值更新到BIT数组中。

2. 单点更新操作

单点更新操作是指对某个特定索引处的元素进行增减操作。这一步是Fenwick树的基本操作之一。

def update(B, i, delta):
    while i < len(B):
        B[i] += delta
        i += lowbit(i)

lowbit函数用于获取i的最低有效位,即(2^k)(其中(0 \leq k \leq 31)):

def lowbit(x):
    return x & -x

3. 前缀和查询操作

前缀和查询是Fenwick树的核心功能之一。给定一个索引i,我们可以通过BIT数组来快速计算出A数组从1到i位置的元素之和。

def query(B, i):
    sum = 0
    while i > 0:
        sum += B[i]
        i -= lowbit(i)
    return sum

4. 区间查询操作

区间查询是指给定两个索引L和R(假设1 ≤ L ≤ R ≤ n),我们需要计算A[L]到A[R]的元素之和。这可以通过前缀和计算得到。

def range_query(B, L, R):
    return query(B, R) - query(B, L - 1)

5. 实现示例

以下是一个完整的Python实现示例:

def lowbit(x):
    return x & -x

def init(A, n):
    B = [0] * (n + 1)
    for i in range(1, n + 1):
        update(B, i, A[i - 1])
    return B

def update(B, i, delta):
    while i < len(B):
        B[i] += delta
        i += lowbit(i)

def query(B, i):
    sum = 0
    while i > 0:
        sum += B[i]
        i -= lowbit(i)
    return sum

def range_query(B, L, R):
    return query(B, R) - query(B, L - 1)

# 示例使用
A = [3, 2, 1, 5, 6, 4]
n = len(A)
B = init(A, n)

print("Initial BIT array:", B)
update(B, 3, 2)
print("Updated BIT array after update(3, 2):", B)
print("Range sum of [1, 4]:", range_query(B, 1, 4))

通过上述步骤,我们可以看到Fenwick树在进行单点更新和区间查询时表现出了高效性。这种数据结构非常适合需要频繁更新和查询的场景。