{
    "slug": "fenwick_tree",
    "term": "Fenwick Tree (Binary Indexed Tree)",
    "category": "data_structures",
    "difficulty": "advanced",
    "short": "A compact array-backed structure giving O(log n) prefix-sum queries and O(log n) point updates with minimal code and memory overhead.",
    "long": "A Fenwick Tree, also called a Binary Indexed Tree (BIT), is a 1-indexed array where each cell stores the sum of a power-of-two-sized range of original values. The size of that range is determined by the lowest set bit of the index, so traversal up or down the implicit tree is done with simple bit tricks: `i += i & -i` to move to the next responsible parent during updates, and `i -= i & -i` to walk prefix segments during queries. Both operations are O(log n), and the structure uses exactly n+1 array slots with no node objects or pointers. Fenwick Trees solve the classic running-totals problem: given an array that mutates over time, answer 'what is the sum of elements 1..k?' or 'what is the sum of elements l..r?' (via two prefix queries) without rescanning. Compared to a Segment Tree, Fenwick is roughly half the code, half the memory, and slightly faster in practice for pure prefix-sum workloads, at the cost of being harder to extend to arbitrary range queries like min/max. Common applications include real-time leaderboard scoring, inversion counting in merge-sort-style algorithms, cumulative frequency tables for statistics, and order-book or analytics rollups where individual cells change frequently and dashboards need fast aggregates. The structure can be generalised: 2D Fenwick Trees support O(log n * log m) updates on a grid, and range-update/range-query variants exist using two parallel BITs. For databases, you would typically use MySQL window functions for one-off rollups, but a Fenwick Tree wins when updates and queries are interleaved at high frequency in application memory.",
    "aliases": [
        "binary indexed tree",
        "BIT",
        "Fenwick BIT"
    ],
    "tags": [
        "data-structures",
        "binary-indexed-tree",
        "prefix-sum",
        "algorithms",
        "competitive-programming"
    ],
    "misconception": "A Fenwick Tree is just a slower segment tree, so always reach for a segment tree. In reality Fenwick is smaller, faster, and easier to write when you only need prefix sums or invertible aggregates.",
    "why_it_matters": "When a dataset has frequent point updates and frequent range-sum queries, naive recomputation is O(n) per query and tanks dashboards or leaderboards under load; Fenwick Trees turn both operations into O(log n), making real-time analytics feasible.",
    "common_mistakes": [
        "Using 0-based indexing internally — the `i & -i` trick requires 1-based indices, and a zero index loops forever.",
        "Trying to support non-invertible operations like min or max — Fenwick relies on subtraction to derive range queries, so use a segment tree for those.",
        "Forgetting to size the array as n+1, causing off-by-one overflows at the last index.",
        "Rebuilding the tree on every update instead of using the O(log n) update path.",
        "Computing range sums as a single walk instead of `prefix(r) - prefix(l-1)`."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "segment_tree",
        "array_data_structure",
        "sql_window_functions",
        "binary_tree"
    ],
    "prerequisites": [
        "array_data_structure",
        "big_o_notation",
        "binary_tree"
    ],
    "refs": [
        "https://en.wikipedia.org/wiki/Fenwick_tree",
        "https://cp-algorithms.com/data_structures/fenwick.html",
        "https://dl.acm.org/doi/10.1002/spe.4380240306"
    ],
    "bad_code": "<?php\n// Naive: O(n) per range-sum query, O(1) per update.\n// Fine for a few hundred rows; collapses on hot leaderboards.\nclass LeaderboardNaive {\n    private array $scores; // 1-indexed\n    private int $n;\n\n    public function __construct(int $n) {\n        $this->n = $n;\n        $this->scores = array_fill(0, $n + 1, 0);\n    }\n\n    public function update(int $userId, int $delta): void {\n        $this->scores[$userId] += $delta;\n    }\n\n    // O(n) — walks the whole prefix every call.\n    public function topRankCumulative(int $rank): int {\n        $sum = 0;\n        for ($i = 1; $i <= $rank; $i++) {\n            $sum += $this->scores[$i];\n        }\n        return $sum;\n    }\n}\n\n// MySQL equivalent that re-scans on every dashboard refresh:\n// SELECT SUM(score) FROM leaderboard WHERE rank <= ?;\n// Each call is O(n) in the index range — no incremental structure.",
    "good_code": "<?php\n// Fenwick Tree: O(log n) update, O(log n) prefix query.\nfinal class FenwickTree {\n    private array $tree;\n    private int $n;\n\n    public function __construct(int $n) {\n        $this->n = $n;\n        $this->tree = array_fill(0, $n + 1, 0); // 1-indexed\n    }\n\n    public function update(int $i, int $delta): void {\n        for (; $i <= $this->n; $i += $i & -$i) {\n            $this->tree[$i] += $delta;\n        }\n    }\n\n    public function prefixSum(int $i): int {\n        $sum = 0;\n        for (; $i > 0; $i -= $i & -$i) {\n            $sum += $this->tree[$i];\n        }\n        return $sum;\n    }\n\n    public function rangeSum(int $l, int $r): int {\n        return $this->prefixSum($r) - $this->prefixSum($l - 1);\n    }\n}\n\n// Usage: leaderboard cumulative scores in-memory, mirrored from MySQL.\n// CREATE TABLE leaderboard (user_id INT PRIMARY KEY, score INT);\n// On score change: $bit->update($userId, $delta) plus single-row UPDATE.\n// Dashboard 'sum of top K ranks' is now O(log n) instead of O(n).",
    "quick_fix": "Replace O(n) prefix-sum loops over mutating arrays with a Fenwick Tree using `i += i & -i` for updates and `i -= i & -i` for queries on a 1-indexed array.",
    "severity": "low",
    "effort": "high",
    "created": "2026-05-18",
    "updated": "2026-05-18",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/fenwick_tree",
        "html_url": "https://codeclaritylab.com/glossary/fenwick_tree",
        "json_url": "https://codeclaritylab.com/glossary/fenwick_tree.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Fenwick Tree (Binary Indexed Tree)](https://codeclaritylab.com/glossary/fenwick_tree) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/fenwick_tree"
            }
        }
    }
}