Fenwick tree
Fenwick Tree
StructureFenwick tree#✓fully proved
A Fenwick tree (binary indexed tree) over a commutative additive monoid \(\alpha\) is an array of elements of \(\alpha\), read as one-indexed interval sums with an unused dummy entry at index \(0\). The structure itself imposes no condition on the entries, and the underlying array it represents is not stored; the relation saying that a tree represents a given array is defined separately.
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
Used by 15
DefinitionLowest set bit#✓fully proved
For a natural number \(n > 0\), \(\operatorname{lowbit}(n)\) is the largest power of two dividing \(n\); for \(n = 0\) it is defined as \(\operatorname{lowbit}(0) = 0\).
public def lowbit (n : Nat) : Nat :=
if n = 0 then 0 else lowbitAux n n
@[no_expose] private def lowbitAux : Nat → Nat → Nat
| 0, _ => 1
| fuel + 1, n => if n % 2 = 1 then 1 else 2 * lowbitAux fuel (n / 2)
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:70
Used by 14
TheoremLowbit of zero#✓fully proved
By convention, \(\operatorname{lowbit}(0) = 0\).
public theorem lowbit_zero : lowbit 0 = 0
public def lowbit (n : Nat) : Nat :=
if n = 0 then 0 else lowbitAux n n
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:81
Uses 1
TheoremThe lowest set bit of a positive number is positive#✓fully proved
For every natural number \(n > 0\), \(\operatorname{lowbit}(n) > 0\), where \(\operatorname{lowbit}(n)\) is the value of the lowest set bit of \(n\) in binary.
public theorem lowbit_pos {n : Nat} (hn : 0 < n) : 0 < lowbit n
public def lowbit (n : Nat) : Nat :=
if n = 0 then 0 else lowbitAux n n
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:81
Uses 1 · Used by 2
TheoremThe lowest set bit is at most the number#✓fully proved
For every natural number \(n\), \(\operatorname{lowbit}(n) \le n\), where \(\operatorname{lowbit}(n)\) is the value of the lowest set bit of \(n\) in binary (with \(\operatorname{lowbit}(0) = 0\)).
public theorem lowbit_le (n : Nat) : lowbit n ≤ n
public def lowbit (n : Nat) : Nat :=
if n = 0 then 0 else lowbitAux n n
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:81
Uses 1 · Used by 2
TheoremThe lowest set bit divides the number#✓fully proved
For every natural number \(n > 0\), \(\operatorname{lowbit}(n)\) divides \(n\), where \(\operatorname{lowbit}(n)\) is the value of the lowest set bit of \(n\) in binary.
public theorem lowbit_dvd {n : Nat} (hn : 0 < n) : lowbit n ∣ n
public def lowbit (n : Nat) : Nat :=
if n = 0 then 0 else lowbitAux n n
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:81
Uses 1 · Used by 1
TheoremThe lowest set bit is a power of two#✓fully proved
For every natural number \(n > 0\), \(\operatorname{lowbit}(n)\) is a power of two: \(\operatorname{lowbit}(n) = 2^k\) for some natural number \(k\).
public theorem lowbit_two_pow {n : Nat} (hn : 0 < n) : ∃ k, lowbit n = 2 ^ k
public def lowbit (n : Nat) : Nat :=
if n = 0 then 0 else lowbitAux n n
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:81
Uses 1 · Used by 1
TheoremDividing out the lowest set bit leaves an odd number#✓fully proved
For every natural number \(n > 0\), the quotient \(n / \operatorname{lowbit}(n)\) is odd, where \(\operatorname{lowbit}(n)\) is the value of the lowest set bit of \(n\) in binary.
public theorem lowbit_div_odd {n : Nat} (hn : 0 < n) : (n / lowbit n) % 2 = 1
public def lowbit (n : Nat) : Nat :=
if n = 0 then 0 else lowbitAux n n
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:81
Uses 1 · Used by 1
DefinitionFenwick-tree interval sum of a list#✓fully proved
For a list \(a\) of elements of a commutative additive monoid \(\alpha\) and a natural number \(j\), the interval sum at the one-indexed position \(j\) is the sum of the \(\operatorname{lowbit}(j)\) entries of \(a\) ending at zero-indexed position \(j - 1\), where \(\operatorname{lowbit}(j)\) is the largest power of two dividing \(j\) (with \(\operatorname{lowbit}(0) = 0\)) and entries past the end of \(a\) count as \(0\).
@[expose] public def blockSum {α : Type u} [AddCommMonoid α] (arr : List α) (j : Nat) : α :=
((List.range' (j - lowbit j) (lowbit j)).map (fun i => arr.getD i 0)).sum
public def lowbit (n : Nat) : Nat :=
if n = 0 then 0 else lowbitAux n n
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:81
DefinitionInterval sum read from an array#✓fully proved
For an array \(a\) of elements of a commutative additive monoid \(\alpha\) and a natural number \(j\), this is the sum of the \(\operatorname{lowbit}(j)\) entries of \(a\) ending at zero-indexed position \(j - 1\), where \(\operatorname{lowbit}(j)\) is the largest power of two dividing \(j\) (with \(\operatorname{lowbit}(0) = 0\)) and entries past the end of \(a\) count as \(0\).
It has the same value as the list-based interval sum but reads each entry in constant time; Fenwick-tree construction uses it, so building takes \(O(n \log n)\) reads rather than quadratic list indexing.
@[expose] public def blockSumArray {α : Type u} [AddCommMonoid α]
(arr : Array α) (j : Nat) : α :=
((List.range' (j - lowbit j) (lowbit j)).map (fun i => arr.getD i 0)).sum
public def lowbit (n : Nat) : Nat :=
if n = 0 then 0 else lowbitAux n n
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:81
Uses 1 · Used by 3
DefinitionFenwick tree representing a list#✓fully proved
A Fenwick tree \(t\) over an additive commutative monoid represents a list \(a\) of length \(n\) when its stored array has length \(n + 1\) (a dummy entry at index \(0\) plus one entry per element of \(a\)) and, for every \(j\) with \(1 \le j \le n\), the stored entry at index \(j\) equals the block sum of \(a\) at \(j\): the sum of the \(\operatorname{lowbit}(j)\) entries of \(a\) ending at position \(j - 1\) (positions counted from \(0\)), where \(\operatorname{lowbit}(j)\) is the largest power of two dividing \(j\).
The underlying list itself is not stored at runtime; it appears only in this specification relation.
@[expose] public def Valid {α : Type u} [AddCommMonoid α] (t : FenwickTree α)
(arr : List α) : Prop :=
t.bit.size = arr.length + 1 ∧
∀ j, 1 ≤ j → j ≤ arr.length → t.bit.getD j 0 = blockSum arr j
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
@[expose] public def blockSum {α : Type u} [AddCommMonoid α] (arr : List α) (j : Nat) : α :=
((List.range' (j - lowbit j) (lowbit j)).map (fun i => arr.getD i 0)).sum
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:379
Uses 2 · Used by 6
DefinitionSize of a Fenwick tree#✓fully proved
The size of a Fenwick tree is the length of its stored array minus one, truncated at \(0\); the one accounts for the dummy entry at index \(0\). It is read off the stored array in constant time.
public def size {α : Type u} [AddCommMonoid α] (t : FenwickTree α) : Nat :=
t.bit.size - 1
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
Uses 1 · Used by 7
TheoremA Fenwick tree has the length of the list it represents#✓fully proved
If a Fenwick tree \(t\) over an additive commutative monoid represents a list \(a\), then the size of \(t\) equals the length of \(a\).
public theorem size_eq_length_of_valid {α : Type u} [AddCommMonoid α]
{t : FenwickTree α} {arr : List α} (hv : Valid t arr) :
t.size = arr.length
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
@[expose] public def Valid {α : Type u} [AddCommMonoid α] (t : FenwickTree α)
(arr : List α) : Prop :=
t.bit.size = arr.length + 1 ∧
∀ j, 1 ≤ j → j ≤ arr.length → t.bit.getD j 0 = blockSum arr j
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:430
Uses 4 · Used by 2
DefinitionBuilding a Fenwick tree from a list#✓fully proved
For a list \(a\) of length \(n\) over a commutative additive monoid \(\alpha\), the Fenwick tree built from \(a\) stores the array of length \(n + 1\) whose entry at index \(0\) is \(0\) and whose entry at each one-indexed position \(j\) with \(1 \le j \le n\) is the sum of the \(\operatorname{lowbit}(j)\) entries of \(a\) ending at zero-indexed position \(j - 1\), where \(\operatorname{lowbit}(j)\) is the largest power of two dividing \(j\).
The input is converted to an array once, so each entry read is constant-time and construction is \(O(n \log n)\).
public def build {α : Type u} [AddCommMonoid α] (arr : List α) : FenwickTree α where
bit :=
let a := arr.toArray
(0 :: (List.range arr.length).map
(fun i => blockSumArray a (i + 1))).toArray
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
@[expose] public def blockSumArray {α : Type u} [AddCommMonoid α]
(arr : Array α) (j : Nat) : α :=
((List.range' (j - lowbit j) (lowbit j)).map (fun i => arr.getD i 0)).sum
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:386
Uses 2 · Used by 3
TheoremSize of a built Fenwick tree#✓fully proved
For every list \(a\) over an additive commutative monoid, the Fenwick tree built from \(a\) has size equal to the length of \(a\).
public theorem size_build {α : Type u} [AddCommMonoid α] (arr : List α) :
(build arr).size = arr.length
public def build {α : Type u} [AddCommMonoid α] (arr : List α) : FenwickTree α where
bit :=
let a := arr.toArray
(0 :: (List.range arr.length).map
(fun i => blockSumArray a (i + 1))).toArray
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:451
Uses 4
TheoremBuilding a Fenwick tree yields a valid representation#✓fully proved
For every list \(a\) over an additive commutative monoid, the Fenwick tree built from \(a\) represents \(a\).
public theorem valid_build {α : Type u} [AddCommMonoid α] (arr : List α) :
Valid (build arr) arr
@[expose] public def Valid {α : Type u} [AddCommMonoid α] (t : FenwickTree α)
(arr : List α) : Prop :=
t.bit.size = arr.length + 1 ∧
∀ j, 1 ≤ j → j ≤ arr.length → t.bit.getD j 0 = blockSum arr j
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:430
public def build {α : Type u} [AddCommMonoid α] (arr : List α) : FenwickTree α where
bit :=
let a := arr.toArray
(0 :: (List.range arr.length).map
(fun i => blockSumArray a (i + 1))).toArray
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:451
Uses 6 · Used by 1
DefinitionFenwick tree prefix sum#✓fully proved
Let \(t\) be a Fenwick tree over an additive commutative monoid with \(n\) underlying entries, let \(k\) be a natural number and let \(m = \min(k, n)\). The prefix sum of length \(k\) of \(t\) is the sum of the stored entries of \(t\) at the positions \(j_0 = m\), \(j_{r+1} = j_r - \operatorname{lowbit}(j_r)\), taken for as long as \(j_r > 0\).
When \(t\) represents a list, this is the sum of its first \(m\) entries, so queries past the end are clamped.
public def prefixSum {α : Type u} [AddCommMonoid α] (t : FenwickTree α) (k : Nat) :
α :=
prefixAux t.bit (min k t.size) (min k t.size)
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
@[no_expose] private def prefixAux {α : Type u} [AddCommMonoid α] (bit : Array α) :
Nat → Nat → α
| 0, _ => 0
| fuel + 1, k => if k = 0 then 0 else bit.getD k 0 + prefixAux bit fuel (k - lowbit k)
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:489
Uses 3 · Used by 6
TheoremThe empty prefix sum is zero#✓fully proved
For every Fenwick tree \(t\) over an additive commutative monoid, the prefix sum of length \(0\) of \(t\) is \(0\).
@[simp]
public theorem prefixSum_zero {α : Type u} [AddCommMonoid α] (t : FenwickTree α) :
prefixSum t 0 = 0
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
public def prefixSum {α : Type u} [AddCommMonoid α] (t : FenwickTree α) (k : Nat) :
α :=
prefixAux t.bit (min k t.size) (min k t.size)
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:531
Uses 2
TheoremCorrectness of Fenwick tree prefix sums#✓fully proved
Let \(t\) be a Fenwick tree representing a list \(a\) of elements of an additive commutative monoid. Then for every natural number \(k\), including \(k > |a|\), the prefix sum of length \(k\) of \(t\) equals the sum of the first \(\min(k, |a|)\) entries of \(a\).
public theorem prefixSum_eq_take_sum {α : Type u} [AddCommMonoid α]
(t : FenwickTree α) {arr : List α} (hv : Valid t arr) (k : Nat) :
prefixSum t k = (arr.take k).sum
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
@[expose] public def Valid {α : Type u} [AddCommMonoid α] (t : FenwickTree α)
(arr : List α) : Prop :=
t.bit.size = arr.length + 1 ∧
∀ j, 1 ≤ j → j ≤ arr.length → t.bit.getD j 0 = blockSum arr j
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:430
public def prefixSum {α : Type u} [AddCommMonoid α] (t : FenwickTree α) (k : Nat) :
α :=
prefixAux t.bit (min k t.size) (min k t.size)
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:531
Uses 9 · Used by 3
TheoremPrefix sums of a built Fenwick tree#✓fully proved
For every list \(a\) of elements of an additive commutative monoid and every natural number \(k\), the prefix sum of length \(k\) of the Fenwick tree built from \(a\) equals the sum of the first \(\min(k, |a|)\) entries of \(a\).
public theorem prefixSum_build {α : Type u} [AddCommMonoid α] (arr : List α)
(k : Nat) : prefixSum (build arr) k = (arr.take k).sum
public def prefixSum {α : Type u} [AddCommMonoid α] (t : FenwickTree α) (k : Nat) :
α :=
prefixAux t.bit (min k t.size) (min k t.size)
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:531
public def build {α : Type u} [AddCommMonoid α] (arr : List α) : FenwickTree α where
bit :=
let a := arr.toArray
(0 :: (List.range arr.length).map
(fun i => blockSumArray a (i + 1))).toArray
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:451
Uses 4
DefinitionPoint update of a Fenwick tree#✓fully proved
Let \(t\) be a Fenwick tree over a commutative additive monoid \(\alpha\), let \(n\) be its size (the length of its stored array minus one), let \(i\) be a natural number and let \(\delta \in \alpha\). Adding \(\delta\) at underlying position \(i\) adds \(\delta\) to the stored entries at the one-indexed positions \(j_1 = i + 1\) and \(j_{k+1} = j_k + \operatorname{lowbit}(j_k)\), for as long as \(j_k \le n\), where \(\operatorname{lowbit}(j)\) is the largest power of two dividing \(j\); every other stored entry is left unchanged. In particular, if \(i \ge n\) the tree is unchanged.
Each write is constant-time only when the stored array is uniquely referenced, since a shared array is copied by the first persistent write. The walk is fuelled by the size, which always suffices because the visited positions strictly increase.
public def add {α : Type u} [AddCommMonoid α] (t : FenwickTree α) (i : Nat)
(δ : α) : FenwickTree α where
bit := (walk t.size t.size (i + 1)).foldl (fun b j => addAt b j δ) t.bit
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
@[no_expose] private def walk (n : Nat) : Nat → Nat → List Nat
| 0, _ => []
| fuel + 1, j => if j ≤ n then j :: walk n fuel (j + lowbit j) else []
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:567
@[no_expose] private def addAt {α : Type u} [AddCommMonoid α] (bit : Array α)
(j : Nat) (δ : α) : Array α :=
if h : j < bit.size then bit.set j (bit.getD j 0 + δ) h else bit
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:640
Uses 3 · Used by 3
TheoremOut-of-range point updates leave a Fenwick tree unchanged#✓fully proved
Let \(t\) be a Fenwick tree over a commutative additive monoid \(\alpha\), and let \(n\) be its size (the length of its stored array minus one). For every natural number \(i \ge n\) and every \(\delta \in \alpha\), the point update of \(t\) adding \(\delta\) at position \(i\) returns \(t\) itself.
public theorem add_eq_self_of_le {α : Type u} [AddCommMonoid α]
(t : FenwickTree α) {i : Nat} (hi : t.size ≤ i) (δ : α) :
add t i δ = t
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
public def add {α : Type u} [AddCommMonoid α] (t : FenwickTree α) (i : Nat)
(δ : α) : FenwickTree α where
bit := (walk t.size t.size (i + 1)).foldl (fun b j => addAt b j δ) t.bit
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:695
Uses 4
TheoremPoint update preserves representation#✓fully proved
Let \(t\) be a Fenwick tree over an additive commutative monoid that represents a list \(a\) of length \(n\). For every index \(i < n\) (counting from \(0\)) and every element \(\delta\), the tree obtained from \(t\) by adding \(\delta\) at position \(i\) represents the list obtained from \(a\) by replacing its entry \(a_i\) with \(a_i + \delta\).
public theorem valid_add {α : Type u} [AddCommMonoid α] {t : FenwickTree α}
{arr : List α} (hv : Valid t arr) {i : Nat} (hi : i < arr.length) (δ : α) :
Valid (add t i δ) (arr.set i (arr.getD i 0 + δ))
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
@[expose] public def Valid {α : Type u} [AddCommMonoid α] (t : FenwickTree α)
(arr : List α) : Prop :=
t.bit.size = arr.length + 1 ∧
∀ j, 1 ≤ j → j ≤ arr.length → t.bit.getD j 0 = blockSum arr j
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:430
public def add {α : Type u} [AddCommMonoid α] (t : FenwickTree α) (i : Nat)
(δ : α) : FenwickTree α where
bit := (walk t.size t.size (i + 1)).foldl (fun b j => addAt b j δ) t.bit
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:695
Uses 12 · Used by 1
TheoremPrefix sums after a point update#✓fully proved
Let \(t\) be a Fenwick tree representing a list \(a\) of elements of an additive commutative monoid, let \(i < |a|\) be a position, let \(\delta\) be an element of the monoid, and let \(k\) be any natural number, possibly larger than \(|a|\). Then the prefix sum of length \(k\) of the tree obtained from \(t\) by adding \(\delta\) at position \(i\) equals the prefix sum of length \(k\) of \(t\) plus \(\delta\) if \(i < k\), and equals the prefix sum of length \(k\) of \(t\) if \(k \le i\).
public theorem prefixSum_add {α : Type u} [AddCommMonoid α] {t : FenwickTree α}
{arr : List α} (hv : Valid t arr) {i : Nat} (hi : i < arr.length) (δ : α)
(k : Nat) :
prefixSum (add t i δ) k = prefixSum t k + (if i < k then δ else 0)
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
@[expose] public def Valid {α : Type u} [AddCommMonoid α] (t : FenwickTree α)
(arr : List α) : Prop :=
t.bit.size = arr.length + 1 ∧
∀ j, 1 ≤ j → j ≤ arr.length → t.bit.getD j 0 = blockSum arr j
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:430
public def prefixSum {α : Type u} [AddCommMonoid α] (t : FenwickTree α) (k : Nat) :
α :=
prefixAux t.bit (min k t.size) (min k t.size)
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:531
public def add {α : Type u} [AddCommMonoid α] (t : FenwickTree α) (i : Nat)
(δ : α) : FenwickTree α where
bit := (walk t.size t.size (i + 1)).foldl (fun b j => addAt b j δ) t.bit
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:695
Uses 6
DefinitionFenwick tree range sum#✓fully proved
For a Fenwick tree \(t\) over an additive commutative group and natural numbers \(\mathit{lo}\) and \(\mathit{hi}\), the range sum of \(t\) over \([\mathit{lo}, \mathit{hi})\) is \(0\) if \(\mathit{hi} \le \mathit{lo}\), and otherwise the prefix sum of length \(\mathit{hi}\) of \(t\) minus the prefix sum of length \(\mathit{lo}\) of \(t\).
When \(t\) represents a list, this is the sum of its entries with indices in \([\mathit{lo}, \mathit{hi})\). This is the only Fenwick tree operation that needs additive inverses.
public def rangeSum {α : Type u} [AddCommGroup α] (t : FenwickTree α)
(lo hi : Nat) : α :=
if hi ≤ lo then 0 else prefixSum t hi - prefixSum t lo
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
public def prefixSum {α : Type u} [AddCommMonoid α] (t : FenwickTree α) (k : Nat) :
α :=
prefixAux t.bit (min k t.size) (min k t.size)
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:531
Uses 2 · Used by 1
TheoremCorrectness of Fenwick tree range sums#✓fully proved
Let \(t\) be a Fenwick tree representing a list \(a = (a_0, \dots, a_{n-1})\) of elements of an additive commutative group. Then for all natural numbers \(\mathit{lo}\) and \(\mathit{hi}\), the range sum of \(t\) over \([\mathit{lo}, \mathit{hi})\) equals \(\sum_{\mathit{lo} \le i < \min(\mathit{hi}, n)} a_i\); in particular it is \(0\) when \(\mathit{hi} \le \mathit{lo}\).
public theorem rangeSum_eq {α : Type u} [AddCommGroup α] {t : FenwickTree α}
{arr : List α} (hv : Valid t arr) (lo hi : Nat) :
rangeSum t lo hi = ((arr.take hi).drop lo).sum
public structure FenwickTree (α : Type u) [AddCommMonoid α] where
/-- The one-indexed stored interval sums, with a dummy entry at index `0`,
backed by an `Array` for constant-time reads; writes are constant-time
only when the array is uniquely referenced (a shared array is copied
first). -/
bit : Array α
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:60
@[expose] public def Valid {α : Type u} [AddCommMonoid α] (t : FenwickTree α)
(arr : List α) : Prop :=
t.bit.size = arr.length + 1 ∧
∀ j, 1 ≤ j → j ≤ arr.length → t.bit.getD j 0 = blockSum arr j
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:430
public def rangeSum {α : Type u} [AddCommGroup α] (t : FenwickTree α)
(lo hi : Nat) : α :=
if hi ≤ lo then 0 else prefixSum t hi - prefixSum t lo
CSLibExt/Algorithms/Lean/DataStructures/FenwickTree.lean:771
Uses 5
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.