Lam NguyenLibrary

Library · Data Structures · range queries

Fenwick Tree

#pragma once
#include <bits/stdc++.h>
using namespace std;

template <typename T>
struct FenwickTree {
    int n;
    vector<T> ft;
    FenwickTree(int _n) : n(_n), ft(_n + 1, 0) {}
    FenwickTree(const vector<T>& a) {
        init(a);
    }
    void init(const vector<T>& a) {
        n = a.size();
        ft.assign(n+1, 0);
        for (int i = 1; i <= n; i++) add(i, a[i-1]);
    }
    void add(int i, T u) {
        for (; i <= n; i += i & -i) ft[i] += u;
    }
    T sum(int i) {
        T s = 0;
        for (; i > 0; i -= i & -i) s += ft[i];
        return s;
    }
    T sum(int L, int R) {
        if (L > R) return 0;
        return sum(R) - sum(L-1);
    }
};
class FenwickTree:
    # 1-indexed, as in FenwickTree.h: add(i, u) and sum(i) take i in [1, n]
    def __init__(self, n_or_a):
        if isinstance(n_or_a, int):
            self.n = n_or_a
            self.ft = [0] * (self.n + 1)
        else:
            self.init(n_or_a)

    # build from a list in O(n): push each node's total into its parent
    def init(self, a: list) -> None:
        self.n = len(a)
        self.ft = [0] + list(a)
        for i in range(1, self.n + 1):
            j = i + (i & -i)
            if j <= self.n: self.ft[j] += self.ft[i]

    def add(self, i: int, u) -> None:
        while i <= self.n:
            self.ft[i] += u
            i += i & -i

    # sum(i) = a[1] + ... + a[i]; sum(L, R) = a[L] + ... + a[R]
    def sum(self, L: int, R: int = None):
        if R is not None:
            return self.sum(R) - self.sum(L - 1) if L <= R else 0
        s, i = 0, L
        while i > 0:
            s += self.ft[i]
            i -= i & -i
        return s