树状数组

Binary Indexed Tree

TypeScript
export function useBIT(nums: number[]) {
    const lowbit = (x: number) => x & -x

    const n = nums.length
    const tree = new Array(n + 1).fill(0)

    for (let i = 0; i < n; i++) add(i, nums[i])

    function add(idx: number, val: number) {
        for (let i = idx + 1; i <= n; i += lowbit(i)) tree[i] += val
    }

    function update(idx: number, val: number) {
        add(idx, val - nums[idx])
    }

    function query(idx: number) {
        let res = 0
        for (let i = idx + 1; i > 0; i -= lowbit(i)) res += tree[i]
        return res
    }

    function queryByInterval(left: number, right: number) {
        return query(right) - query(left - 1)
    }

    return {
        add,
        update,
        query,
        queryByInterval,
    }
}
JavaScript
export function useBIT(nums) {
    const lowbit = (x) => x & -x
    const n = nums.length
    const tree = new Array(n + 1).fill(0)
    for (let i = 0; i < n; i++) add(i, nums[i])
    function add(idx, val) {
        for (let i = idx + 1; i <= n; i += lowbit(i)) tree[i] += val
    }
    function update(idx, val) {
        add(idx, val - nums[idx])
    }
    function query(idx) {
        let res = 0
        for (let i = idx + 1; i > 0; i -= lowbit(i)) res += tree[i]
        return res
    }
    function queryByInterval(left, right) {
        return query(right) - query(left - 1)
    }
    return {
        add,
        update,
        query,
        queryByInterval,
    }
}
Rust
pub struct BIT {
    n: usize,
    tree: Vec<i64>,
}

impl BIT {
    pub fn new(n: usize) -> Self {
        BIT {
            n,
            tree: vec![0; n + 1],
        }
    }

    pub fn add(&mut self, i: usize, x: i64) {
        let mut i = i + 1;
        while i <= self.n {
            self.tree[i] += x;
            i += i & i.wrapping_neg();
        }
    }

    pub fn query(&self, i: usize) -> i64 {
        let mut s = 0;
        let mut i = i + 1;
        while i > 0 {
            s += self.tree[i];
            i -= i & i.wrapping_neg();
        }
        s
    }
}
Java

class BinaryIndexedTree {

    int[] tree, nums;
    int n;

    public BinaryIndexedTree(int[] nums) {
        n = nums.length;
        this.nums = nums;
        // tree 下标以 1 开始
        tree = new int[n + 1];
        for (int i = 0; i < n; i++) {
            add(i, nums[i]);
        }
    }

    /**
     * 在指定下标增加值
     *
     * @param idx 指定数组下标
     * @param val 要增加的值(不是修改,是增加)
     */
    public final void add(int idx, int val) {
        for (int i = idx + 1; i <= n; i += lowbit(i)) {
            tree[i] += val;
        }
    }

    /**
     * 更新指定下标的值
     *
     * @param idx 指定数组下标
     * @param val 要更新的值
     */
    public void update(int idx, int val) {
        add(idx, val - nums[idx]);
        nums[idx] = val;
    }

    /**
     * 查找前缀和
     *
     * @param idx 查询的右端点
     * @return nums[0:idx] 的和
     */
    public int query(int idx) {
        int res = 0;
        for (int i = idx + 1; i > 0; i -= lowbit(i)) {
            res += tree[i];
        }
        return res;
    }

    /**
     * 查询[left, right]区间和
     *
     * @param left  左端点(闭)
     * @param right 右端点(闭)
     */
    public int query(int left, int right) {
        return query(right) - query(left - 1);
    }

    private int lowbit(int x) {
        return x & -x;
    }
}