From ae66cd7045b79e20f8f48b897b457c4ab6dbd1c8 Mon Sep 17 00:00:00 2001 From: freakin23 Date: Sun, 9 Nov 2025 21:42:27 +0530 Subject: [PATCH 01/20] make language consistent --- src/data_structures/fenwick.md | 45 ++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 439885b83..0069e6990 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -431,30 +431,37 @@ Thus we can use $B_2$ for shaving off extra terms when we multiply $B_1[i]\times We can find arbitrary range sums by computing the prefix sums for $l-1$ and $r$ and taking the difference of them again. -```python -def add(b, idx, x): - while idx <= N: - b[idx] += x - idx += idx & -idx +```cpp +void add(std::vector b, int idx, int x) { + while (idx <= n) { + b[idx] += x; + idx += idx & -idx; + } +} -def range_add(l,r,x): +void range_add(int l, int r, int x) { add(B1, l, x) - add(B1, r+1, -x) - add(B2, l, x*(l-1)) - add(B2, r+1, -x*r) + add(B1, r + 1, -x) + add(B2, l, x * (l - 1)) + add(B2, r + 1, -x * r) +} -def sum(b, idx): - total = 0 - while idx > 0: - total += b[idx] - idx -= idx & -idx - return total +int sum(std::vector b, int idx) { + int total = 0; + while (idx > 0) { + total += b[idx]; + idx -= idx & -idx; + } + return total; +} -def prefix_sum(idx): - return sum(B1, idx)*idx - sum(B2, idx) +int prefix_sum(int idx) { + return sum(B1, idx) * idx - sum(B2, idx); +} -def range_sum(l, r): - return prefix_sum(r) - prefix_sum(l-1) +int range_sum(int l, int r) { + return prefix_sum(r) - prefix_sum(l - 1); +} ``` ## Practice Problems From 5fcbbdcf9dc543de0f03556bb67519e5535aa3bc Mon Sep 17 00:00:00 2001 From: freakin23 Date: Tue, 11 Nov 2025 07:16:11 +0530 Subject: [PATCH 02/20] pass reference --- src/data_structures/fenwick.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 0069e6990..eb21ee8b4 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -432,7 +432,7 @@ Thus we can use $B_2$ for shaving off extra terms when we multiply $B_1[i]\times We can find arbitrary range sums by computing the prefix sums for $l-1$ and $r$ and taking the difference of them again. ```cpp -void add(std::vector b, int idx, int x) { +void add(std::vector &b, int idx, int x) { while (idx <= n) { b[idx] += x; idx += idx & -idx; @@ -446,7 +446,7 @@ void range_add(int l, int r, int x) { add(B2, r + 1, -x * r) } -int sum(std::vector b, int idx) { +int sum(std::vector &b, int idx) { int total = 0; while (idx > 0) { total += b[idx]; From 7ba558447fc73a7231bac83777bc1ef6d531a71f Mon Sep 17 00:00:00 2001 From: freakin23 Date: Tue, 11 Nov 2025 07:20:43 +0530 Subject: [PATCH 03/20] add python code too --- src/data_structures/fenwick.md | 73 +++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index eb21ee8b4..edb6848d7 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -431,38 +431,65 @@ Thus we can use $B_2$ for shaving off extra terms when we multiply $B_1[i]\times We can find arbitrary range sums by computing the prefix sums for $l-1$ and $r$ and taking the difference of them again. -```cpp -void add(std::vector &b, int idx, int x) { - while (idx <= n) { - b[idx] += x; - idx += idx & -idx; +=== "C++" + ```cpp + void add(std::vector &b, int idx, int x) { + while (idx <= n) { + b[idx] += x; + idx += idx & -idx; + } + } + + void range_add(int l, int r, int x) { + add(B1, l, x) + add(B1, r + 1, -x) + add(B2, l, x * (l - 1)) + add(B2, r + 1, -x * r) + } + + int sum(std::vector &b, int idx) { + int total = 0; + while (idx > 0) { + total += b[idx]; + idx -= idx & -idx; + } + return total; + } + + int prefix_sum(int idx) { + return sum(B1, idx) * idx - sum(B2, idx); } -} -void range_add(int l, int r, int x) { + int range_sum(int l, int r) { + return prefix_sum(r) - prefix_sum(l - 1); + } +``` +=== "Python" + ```py + def add(b, idx, x): + while idx <= N: + b[idx] += x + idx += idx & -idx + +def range_add(l,r,x): add(B1, l, x) add(B1, r + 1, -x) add(B2, l, x * (l - 1)) add(B2, r + 1, -x * r) -} -int sum(std::vector &b, int idx) { - int total = 0; - while (idx > 0) { - total += b[idx]; - idx -= idx & -idx; - } - return total; -} +def sum(b, idx): + total = 0 + while idx > 0: + total += b[idx] + idx -= idx & -idx + return total -int prefix_sum(int idx) { - return sum(B1, idx) * idx - sum(B2, idx); -} +def prefix_sum(idx): + return sum(B1, idx) * idx - sum(B2, idx) -int range_sum(int l, int r) { - return prefix_sum(r) - prefix_sum(l - 1); -} -``` +def range_sum(l, r): + return prefix_sum(r) - prefix_sum(l - 1) + ``` ## Practice Problems From fb6dce2c3dc253d003c699e99a18ee94af04f069 Mon Sep 17 00:00:00 2001 From: freakin23 Date: Tue, 11 Nov 2025 07:21:09 +0530 Subject: [PATCH 04/20] formatting --- src/data_structures/fenwick.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index edb6848d7..f33b48a40 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -398,9 +398,9 @@ And we also update $B_2$. The details will be explained later. ```python def range_add(l, r, x): add(B1, l, x) - add(B1, r+1, -x) - add(B2, l, x*(l-1)) - add(B2, r+1, -x*r)) + add(B1, r + 1, -x) + add(B2, l, x * (l - 1)) + add(B2, r + 1, -x * r)) ``` After the range update $(l, r, x)$ the range sum query should return the following values: From 8661451eb40581186b96d804d346d39954415554 Mon Sep 17 00:00:00 2001 From: freakin23 Date: Tue, 11 Nov 2025 07:24:05 +0530 Subject: [PATCH 05/20] formatting --- src/data_structures/fenwick.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index f33b48a40..69e243764 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -471,24 +471,24 @@ We can find arbitrary range sums by computing the prefix sums for $l-1$ and $r$ b[idx] += x idx += idx & -idx -def range_add(l,r,x): - add(B1, l, x) - add(B1, r + 1, -x) - add(B2, l, x * (l - 1)) - add(B2, r + 1, -x * r) + def range_add(l,r,x): + add(B1, l, x) + add(B1, r + 1, -x) + add(B2, l, x * (l - 1)) + add(B2, r + 1, -x * r) -def sum(b, idx): - total = 0 - while idx > 0: - total += b[idx] - idx -= idx & -idx - return total + def sum(b, idx): + total = 0 + while idx > 0: + total += b[idx] + idx -= idx & -idx + return total -def prefix_sum(idx): - return sum(B1, idx) * idx - sum(B2, idx) + def prefix_sum(idx): + return sum(B1, idx) * idx - sum(B2, idx) -def range_sum(l, r): - return prefix_sum(r) - prefix_sum(l - 1) + def range_sum(l, r): + return prefix_sum(r) - prefix_sum(l - 1) ``` ## Practice Problems From 73a326b626e60e2bd2ac701f50cd74f9e09cc30d Mon Sep 17 00:00:00 2001 From: Rameez Parwez <79394137+Sosuke23@users.noreply.github.com> Date: Tue, 11 Nov 2025 18:25:07 +0530 Subject: [PATCH 06/20] Update fenwick.md --- src/data_structures/fenwick.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 69e243764..fe6befa3c 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -463,7 +463,7 @@ We can find arbitrary range sums by computing the prefix sums for $l-1$ and $r$ int range_sum(int l, int r) { return prefix_sum(r) - prefix_sum(l - 1); } -``` + ``` === "Python" ```py def add(b, idx, x): From 5bb8de0fd3f03c64d2263601bf31b439323e90a7 Mon Sep 17 00:00:00 2001 From: freakin23 Date: Sat, 22 Nov 2025 12:48:37 +0530 Subject: [PATCH 07/20] python code for range update and point query --- src/data_structures/fenwick.md | 52 +++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index fe6befa3c..433f232f3 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -366,24 +366,44 @@ And if $i > r$, then the second update operation will cancel the effect of first The following implementation uses one-based indexing. -```cpp -void add(int idx, int val) { - for (++idx; idx < n; idx += idx & -idx) - bit[idx] += val; -} +=== "C++" + ```cpp + void add(int idx, int val) { + for (++idx; idx < n; idx += idx & -idx) + bit[idx] += val; + } -void range_add(int l, int r, int val) { - add(l, val); - add(r + 1, -val); -} + void range_add(int l, int r, int val) { + add(l, val); + add(r + 1, -val); + } -int point_query(int idx) { - int ret = 0; - for (++idx; idx > 0; idx -= idx & -idx) - ret += bit[idx]; - return ret; -} -``` + int point_query(int idx) { + int ret = 0; + for (++idx; idx > 0; idx -= idx & -idx) + ret += bit[idx]; + return ret; + } + ``` +=== "Python" + ```py + def add(idx: int, val: int) -> None: + while idx <= n: + bit[idx] += val + idx += idx & -idx + + def range_add(l: int, r: int, val: int) -> None: + add(l, val) + add(r + 1, -val) + + def point_query(idx: int) -> int: + ret = 0 + while idx > 0: + ret += bit[idx] + idx -= idx & -idx + + return ret + ``` Note: of course it is also possible to increase a single point $A[i]$ with `range_add(i, i, val)`. From 776a9f876ea03993af7ef6ab70f11a8004dc1d5c Mon Sep 17 00:00:00 2001 From: freakin23 Date: Sat, 22 Nov 2025 13:05:10 +0530 Subject: [PATCH 08/20] minor changes --- src/data_structures/fenwick.md | 47 ++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 433f232f3..8d85979bd 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -50,14 +50,14 @@ Now we can write some pseudo-code for the two operations mentioned above. Below, we get the sum of elements of $A$ in the range $[0, r]$ and update (increase) some element $A_i$: ```python -def sum(int r): +def sum(r: int): res = 0 while (r >= 0): res += t[r] r = g(r) - 1 return res -def increase(int i, int delta): +def increase(i: int, delta: int): for all j with g(j) <= i <= j: t[j] += delta ``` @@ -271,14 +271,14 @@ We want $T[i]$ to store the sum of $[g(i)+1; i]$. This changes the implementation a little bit, and allows for a similar nice definition for $g(i)$: ```python -def sum(int r): +def sum(r: int): res = 0 while (r > 0): res += t[r] r = g(r) return res -def increase(int i, int delta): +def increase(i: int, delta: int): for all j with g(j) < i <= j: t[j] += delta ``` @@ -415,13 +415,22 @@ Suppose that we want to increment the interval $[l, r]$ by the value $x$. Similarly as in the previous method, we perform two point updates on $B_1$: `add(B1, l, x)` and `add(B1, r+1, -x)`. And we also update $B_2$. The details will be explained later. -```python -def range_add(l, r, x): - add(B1, l, x) - add(B1, r + 1, -x) - add(B2, l, x * (l - 1)) - add(B2, r + 1, -x * r)) -``` +=== "C++" + ```cpp + void range_add(int l, int r, int x) { + add(B1, l, x) + add(B1, r + 1, -x) + add(B2, l, x * (l - 1)) + add(B2, r + 1, -x * r) + } +=== "Python" + ```py + def range_add(l: int, r: int, x: int): + add(B1, l, x) + add(B1, r + 1, -x) + add(B2, l, x * (l - 1)) + add(B2, r + 1, -x * r) + ``` After the range update $(l, r, x)$ the range sum query should return the following values: $$ @@ -486,28 +495,28 @@ We can find arbitrary range sums by computing the prefix sums for $l-1$ and $r$ ``` === "Python" ```py - def add(b, idx, x): - while idx <= N: - b[idx] += x - idx += idx & -idx + def add(b: list, idx: int, x: int): + while idx <= N: + b[idx] += x + idx += idx & -idx - def range_add(l,r,x): + def range_add(l: int, r: int, x: int): add(B1, l, x) add(B1, r + 1, -x) add(B2, l, x * (l - 1)) add(B2, r + 1, -x * r) - def sum(b, idx): + def sum(b: list, idx: int): total = 0 while idx > 0: total += b[idx] idx -= idx & -idx return total - def prefix_sum(idx): + def prefix_sum(idx: int): return sum(B1, idx) * idx - sum(B2, idx) - def range_sum(l, r): + def range_sum(l: int, r: int): return prefix_sum(r) - prefix_sum(l - 1) ``` From e475c29c6c8954d58e76dab8ad678fedbe64073f Mon Sep 17 00:00:00 2001 From: freakin23 Date: Sat, 22 Nov 2025 13:33:01 +0530 Subject: [PATCH 09/20] add py lang --- src/data_structures/fenwick.md | 160 +++++++++++++++++++++++---------- 1 file changed, 115 insertions(+), 45 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 8d85979bd..545cc2b59 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -49,18 +49,38 @@ Both versions are equivalent in terms of time and memory complexity. Now we can write some pseudo-code for the two operations mentioned above. Below, we get the sum of elements of $A$ in the range $[0, r]$ and update (increase) some element $A_i$: -```python -def sum(r: int): - res = 0 - while (r >= 0): - res += t[r] - r = g(r) - 1 - return res - -def increase(i: int, delta: int): - for all j with g(j) <= i <= j: - t[j] += delta -``` +=== "C++" + ```cpp + int sum(int r) { + int res = 0; + while (r >= 0) { + res += t[r]; + r = g(r) - 1; + } + return res; + } + + void increase(int i, int delta) { + for (int j = 0; j < t.size(); j++) { + if (g(j) <= i && i <= j) { + t[j] += delta; + } + } + } + ``` +=== "Python" + ```py + def sum(r: int): + res = 0 + while (r >= 0): + res += t[r] + r = g(r) - 1 + return res + + def increase(i: int, delta: int): + for all j with g(j) <= i <= j: + t[j] += delta + ``` The function `sum` works as follows: @@ -241,28 +261,58 @@ The implementation is also a lot harder compared to the normal implementation fo As claimed before, it is very easy to implement Fenwick Tree for multidimensional array. -```cpp -struct FenwickTree2D { - vector> bit; - int n, m; - - // init(...) { ... } - - int sum(int x, int y) { - int ret = 0; - for (int i = x; i >= 0; i = (i & (i + 1)) - 1) - for (int j = y; j >= 0; j = (j & (j + 1)) - 1) - ret += bit[i][j]; - return ret; - } +=== "C++" + ```cpp + struct FenwickTree2D { + vector> bit; + int n, m; + + // init(...) { ... } + + int sum(int x, int y) { + int ret = 0; + for (int i = x; i >= 0; i = (i & (i + 1)) - 1) + for (int j = y; j >= 0; j = (j & (j + 1)) - 1) + ret += bit[i][j]; + return ret; + } - void add(int x, int y, int delta) { - for (int i = x; i < n; i = i | (i + 1)) - for (int j = y; j < m; j = j | (j + 1)) - bit[i][j] += delta; - } -}; -``` + void add(int x, int y, int delta) { + for (int i = x; i < n; i = i | (i + 1)) + for (int j = y; j < m; j = j | (j + 1)) + bit[i][j] += delta; + } + }; + ``` +=== "Python" + ```py + class FenwickTree2D: + + def __init__(self, n: int, m: int) -> None: + self.n = n + self.m = m + self.bit = [[0] * m for _ in range(n)] + + def sum(self, x: int, y: int) -> int: + ret = 0 + i = x + while i >= 0: + j = y + while j >= 0: + ret += self.bit[i][j] + j = (j & (j + 1)) - 1 + i = (i & (i + 1)) - 1 + return ret + + def add(self, x: int, y: int, delta: int) -> None: + i = x + while i < self.n: + j = y + while j < self.m: + self.bit[i][j] += delta + j = j | (j + 1) + i = i | (i + 1) + ``` ### One-based indexing approach @@ -270,18 +320,38 @@ For this approach we change the requirements and definition for $T[]$ and $g()$ We want $T[i]$ to store the sum of $[g(i)+1; i]$. This changes the implementation a little bit, and allows for a similar nice definition for $g(i)$: -```python -def sum(r: int): - res = 0 - while (r > 0): - res += t[r] - r = g(r) - return res - -def increase(i: int, delta: int): - for all j with g(j) < i <= j: - t[j] += delta -``` +=== "C++" + ```cpp + int sum(int r) { + int res = 0; + while (r > 0) { + res += t[r]; + r = g(r); + } + return res; + } + + void increase(int i, int delta) { + for (int j = 0; j < t.size(); j++) { + if (g(j) < i && i <= j) { + t[j] += delta; + } + } + } + ``` +=== "Python" + ```py + def sum(r: int) -> int: + res = 0 + while (r > 0): + res += t[r] + r = g(r) + return res + + def increase(i: int, delta: int) -> None: + for all j with g(j) < i <= j: + t[j] += delta + ``` The computation of $g(i)$ is defined as: toggling of the last set $1$ bit in the binary representation of $i$. From d6c2b5f5a31eff5766a91f8252675a17cb4c1ae2 Mon Sep 17 00:00:00 2001 From: freakin23 Date: Sat, 22 Nov 2025 13:49:45 +0530 Subject: [PATCH 10/20] add py lang --- src/data_structures/fenwick.md | 90 ++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 545cc2b59..f3c038d72 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -374,40 +374,70 @@ As you can see, the main benefit of this approach is that the binary operations The following implementation can be used like the other implementations, however it uses one-based indexing internally. -```{.cpp file=fenwick_sum_onebased} -struct FenwickTreeOneBasedIndexing { - vector bit; // binary indexed tree - int n; - - FenwickTreeOneBasedIndexing(int n) { - this->n = n + 1; - bit.assign(n + 1, 0); - } - - FenwickTreeOneBasedIndexing(vector a) - : FenwickTreeOneBasedIndexing(a.size()) { - for (size_t i = 0; i < a.size(); i++) - add(i, a[i]); - } +=== "C++" + ```{.cpp file=fenwick_sum_onebased} + struct FenwickTreeOneBasedIndexing { + vector bit; // binary indexed tree + int n; + + FenwickTreeOneBasedIndexing(int n) { + this->n = n + 1; + bit.assign(n + 1, 0); + } - int sum(int idx) { - int ret = 0; - for (++idx; idx > 0; idx -= idx & -idx) - ret += bit[idx]; - return ret; - } + FenwickTreeOneBasedIndexing(vector a) + : FenwickTreeOneBasedIndexing(a.size()) { + for (size_t i = 0; i < a.size(); i++) + add(i, a[i]); + } - int sum(int l, int r) { - return sum(r) - sum(l - 1); - } + int sum(int idx) { + int ret = 0; + for (++idx; idx > 0; idx -= idx & -idx) + ret += bit[idx]; + return ret; + } - void add(int idx, int delta) { - for (++idx; idx < n; idx += idx & -idx) - bit[idx] += delta; - } -}; -``` + int sum(int l, int r) { + return sum(r) - sum(l - 1); + } + void add(int idx, int delta) { + for (++idx; idx < n; idx += idx & -idx) + bit[idx] += delta; + } + }; + ``` +=== "Python" + ```py + class FenwickTreeOneBasedIndexing: + + def __init__(self, a: int) -> None: + if isinstance(a, int): + self.n = a + 1 + self.bit = [0] * (a + 1) + else: + self.n = len(n) + 1 + self.bit = [0] * (len(a) + 1) + for i in range(len(a)): + self.add(i, a[i]) + + def sum(self, idx: int) -> int: + ret = 0 + while idx > 0: + ret += self.bit[idx] + idx -= idx & -idx + return ret + + def range_sum(self, l: int, r: int) -> int: + return self.sum(r) - self.sum(l - 1) + + def add(self, idx: int, delta: int) -> None: + while idx <= self.n: + self.bit[idx] += delta + idx += idx & -idx + ``` + ## Range operations A Fenwick tree can support the following range operations: From 4180082f6fdb65c96c5582ab802aec11bc7f67be Mon Sep 17 00:00:00 2001 From: freakin23 Date: Sat, 22 Nov 2025 14:00:19 +0530 Subject: [PATCH 11/20] add py lang --- src/data_structures/fenwick.md | 85 +++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 27 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index f3c038d72..fd647d7b5 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -222,35 +222,66 @@ It is obvious that there is no easy way of finding minimum of range $[l, r]$ usi Additionally, each time a value is `update`'d, the new value has to be smaller than the current value. Both significant limitations are because the $min$ operation together with the set of integers doesn't form a group, as there are no inverse elements. -```{.cpp file=fenwick_min} -struct FenwickTreeMin { - vector bit; - int n; - const int INF = (int)1e9; +=== "C++" + ```{.cpp file=fenwick_min} + struct FenwickTreeMin { + vector bit; + int n; + const int INF = (int)1e9; - FenwickTreeMin(int n) { - this->n = n; - bit.assign(n, INF); - } + FenwickTreeMin(int n) { + this->n = n; + bit.assign(n, INF); + } - FenwickTreeMin(vector a) : FenwickTreeMin(a.size()) { - for (size_t i = 0; i < a.size(); i++) - update(i, a[i]); - } + FenwickTreeMin(vector a) : FenwickTreeMin(a.size()) { + for (size_t i = 0; i < a.size(); i++) + update(i, a[i]); + } - int getmin(int r) { - int ret = INF; - for (; r >= 0; r = (r & (r + 1)) - 1) - ret = min(ret, bit[r]); - return ret; - } + int getmin(int r) { + int ret = INF; + for (; r >= 0; r = (r & (r + 1)) - 1) + ret = min(ret, bit[r]); + return ret; + } - void update(int idx, int val) { - for (; idx < n; idx = idx | (idx + 1)) - bit[idx] = min(bit[idx], val); - } -}; -``` + void update(int idx, int val) { + for (; idx < n; idx = idx | (idx + 1)) + bit[idx] = min(bit[idx], val); + } + }; + ``` +=== "Python" + ```py + class FenwickTreeMin: + + def __init__(self, a: Union[int, List[int]]) -> None: + self.INF = 10**9 + + if isinstance(a, int): + self.n = a + self.bit = [self.INF] * a + else: + self.n = len(a) + self.bit = [self.INF] * len(a) + for i in range(len(a)): + self.update(i, a[i]) + + + def getmin(self, r: int) -> int: + ret = self.INF + while r >= 0: + ret = min(ret, self.bit[r]) + r = (r & (r + 1)) - 1 + + return ret + + def update(self, idx: int, val: int) -> None: + while idx < self.n: + self.bit[idx] = min(self.bit[idx], val) + idx = idx | (idx + 1) + ``` Note: it is possible to implement a Fenwick tree that can handle arbitrary minimum range queries and arbitrary updates. The paper [Efficient Range Minimum Queries using Binary Indexed Trees](http://ioinformatics.org/oi/pdf/v9_2015_39_44.pdf) describes such an approach. @@ -412,7 +443,7 @@ The following implementation can be used like the other implementations, however ```py class FenwickTreeOneBasedIndexing: - def __init__(self, a: int) -> None: + def __init__(self, a: Union[int, List[int]]) -> None: if isinstance(a, int): self.n = a + 1 self.bit = [0] * (a + 1) @@ -437,7 +468,7 @@ The following implementation can be used like the other implementations, however self.bit[idx] += delta idx += idx & -idx ``` - + ## Range operations A Fenwick tree can support the following range operations: From 3d4ca19ea843c06be8bb65915691dcf09722386f Mon Sep 17 00:00:00 2001 From: freakin23 Date: Sat, 22 Nov 2025 14:07:51 +0530 Subject: [PATCH 12/20] add py lang --- src/data_structures/fenwick.md | 84 +++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index fd647d7b5..210bec3ff 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -164,39 +164,69 @@ This is handled in the `sum(int l, int r)` method. Also this implementation supports two constructors. You can create a Fenwick tree initialized with zeros, or you can convert an existing array into the Fenwick form. +=== "C++" + ```{.cpp file=fenwick_sum} + struct FenwickTree { + vector bit; // binary indexed tree + int n; -```{.cpp file=fenwick_sum} -struct FenwickTree { - vector bit; // binary indexed tree - int n; + FenwickTree(int n) { + this->n = n; + bit.assign(n, 0); + } - FenwickTree(int n) { - this->n = n; - bit.assign(n, 0); - } + FenwickTree(vector const &a) : FenwickTree(a.size()) { + for (size_t i = 0; i < a.size(); i++) + add(i, a[i]); + } - FenwickTree(vector const &a) : FenwickTree(a.size()) { - for (size_t i = 0; i < a.size(); i++) - add(i, a[i]); - } + int sum(int r) { + int ret = 0; + for (; r >= 0; r = (r & (r + 1)) - 1) + ret += bit[r]; + return ret; + } - int sum(int r) { - int ret = 0; - for (; r >= 0; r = (r & (r + 1)) - 1) - ret += bit[r]; - return ret; - } + int sum(int l, int r) { + return sum(r) - sum(l - 1); + } - int sum(int l, int r) { - return sum(r) - sum(l - 1); - } + void add(int idx, int delta) { + for (; idx < n; idx = idx | (idx + 1)) + bit[idx] += delta; + } + }; + ``` +=== "Python" + ```py + class FenwickTree: + + def __init__(self, a: Union[int, List[int]]) -> None: - void add(int idx, int delta) { - for (; idx < n; idx = idx | (idx + 1)) - bit[idx] += delta; - } -}; -``` + if isinstance(a, int): + self.n = a + self.bit = [0] * a + else: + self.n = len(a) + self.bit = [0] * len(a) + for i in range(len(a)): + self.add(i, a[i]) + + def sum(self, r: int) -> int: + ret = 0 + while r >= 0: + ret += self.bit[r] + r = (r & (r + 1)) - 1 + return ret + + def range_sum(self, l: int, r: int) -> int: + return self.sum(r) - self.sum(l - 1) + + def add(self, idx: int, delta: int) -> None: + while idx < self.n: + self.bit[idx] += delta + idx = idx | (idx + 1) + ``` ### Linear construction From c668f7ae06bf9346e79015739572d609968a53bb Mon Sep 17 00:00:00 2001 From: freakin23 Date: Sat, 22 Nov 2025 14:10:38 +0530 Subject: [PATCH 13/20] minor changes --- src/data_structures/fenwick.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 210bec3ff..5463a6da4 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -70,14 +70,14 @@ Below, we get the sum of elements of $A$ in the range $[0, r]$ and update (incre ``` === "Python" ```py - def sum(r: int): + def sum(r: int) -> int: res = 0 while (r >= 0): res += t[r] r = g(r) - 1 return res - def increase(i: int, delta: int): + def increase(i: int, delta: int) -> None: for all j with g(j) <= i <= j: t[j] += delta ``` @@ -165,7 +165,7 @@ Also this implementation supports two constructors. You can create a Fenwick tree initialized with zeros, or you can convert an existing array into the Fenwick form. === "C++" - ```{.cpp file=fenwick_sum} + ```cpp struct FenwickTree { vector bit; // binary indexed tree int n; @@ -253,7 +253,7 @@ Additionally, each time a value is `update`'d, the new value has to be smaller t Both significant limitations are because the $min$ operation together with the set of integers doesn't form a group, as there are no inverse elements. === "C++" - ```{.cpp file=fenwick_min} + ```cpp struct FenwickTreeMin { vector bit; int n; @@ -436,7 +436,7 @@ As you can see, the main benefit of this approach is that the binary operations The following implementation can be used like the other implementations, however it uses one-based indexing internally. === "C++" - ```{.cpp file=fenwick_sum_onebased} + ```cpp struct FenwickTreeOneBasedIndexing { vector bit; // binary indexed tree int n; From 0df0a0398640878cfc359e1f5c529e5a02a42eea Mon Sep 17 00:00:00 2001 From: freakin23 Date: Wed, 26 Nov 2025 08:04:03 +0530 Subject: [PATCH 14/20] may solve build issue --- src/data_structures/fenwick.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 5463a6da4..875e084a3 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -165,7 +165,7 @@ Also this implementation supports two constructors. You can create a Fenwick tree initialized with zeros, or you can convert an existing array into the Fenwick form. === "C++" - ```cpp + ```{.cpp file=fenwick_sum} struct FenwickTree { vector bit; // binary indexed tree int n; @@ -253,7 +253,7 @@ Additionally, each time a value is `update`'d, the new value has to be smaller t Both significant limitations are because the $min$ operation together with the set of integers doesn't form a group, as there are no inverse elements. === "C++" - ```cpp + ```{.cpp file=fenwick_min} struct FenwickTreeMin { vector bit; int n; @@ -436,7 +436,7 @@ As you can see, the main benefit of this approach is that the binary operations The following implementation can be used like the other implementations, however it uses one-based indexing internally. === "C++" - ```cpp + ```{.cpp file=fenwick_sum_onebased} struct FenwickTreeOneBasedIndexing { vector bit; // binary indexed tree int n; From 079b8ab41a182d8d4929264dbe400bf75b192212 Mon Sep 17 00:00:00 2001 From: Michael Hayter Date: Fri, 5 Dec 2025 22:25:10 -0800 Subject: [PATCH 15/20] Update fenwick.md try messing with space. --- src/data_structures/fenwick.md | 64 +++++++++++++++++----------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 875e084a3..e4b7bbe9b 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -165,38 +165,38 @@ Also this implementation supports two constructors. You can create a Fenwick tree initialized with zeros, or you can convert an existing array into the Fenwick form. === "C++" - ```{.cpp file=fenwick_sum} - struct FenwickTree { - vector bit; // binary indexed tree - int n; - - FenwickTree(int n) { - this->n = n; - bit.assign(n, 0); - } - - FenwickTree(vector const &a) : FenwickTree(a.size()) { - for (size_t i = 0; i < a.size(); i++) - add(i, a[i]); - } - - int sum(int r) { - int ret = 0; - for (; r >= 0; r = (r & (r + 1)) - 1) - ret += bit[r]; - return ret; - } - - int sum(int l, int r) { - return sum(r) - sum(l - 1); - } - - void add(int idx, int delta) { - for (; idx < n; idx = idx | (idx + 1)) - bit[idx] += delta; - } - }; - ``` +```{.cpp file=fenwick_sum} +struct FenwickTree { + vector bit; // binary indexed tree + int n; + + FenwickTree(int n) { + this->n = n; + bit.assign(n, 0); + } + + FenwickTree(vector const &a) : FenwickTree(a.size()) { + for (size_t i = 0; i < a.size(); i++) + add(i, a[i]); + } + + int sum(int r) { + int ret = 0; + for (; r >= 0; r = (r & (r + 1)) - 1) + ret += bit[r]; + return ret; + } + + int sum(int l, int r) { + return sum(r) - sum(l - 1); + } + + void add(int idx, int delta) { + for (; idx < n; idx = idx | (idx + 1)) + bit[idx] += delta; + } +}; +``` === "Python" ```py class FenwickTree: From f5cf5ec19e5115053cef8b57ae213d97221289e9 Mon Sep 17 00:00:00 2001 From: Michael Hayter Date: Fri, 5 Dec 2025 22:29:22 -0800 Subject: [PATCH 16/20] Update fenwick.md pretty sure spaces are screwing up test file generation. --- src/data_structures/fenwick.md | 110 ++++++++++++++++----------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index e4b7bbe9b..296dfeefc 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -253,35 +253,35 @@ Additionally, each time a value is `update`'d, the new value has to be smaller t Both significant limitations are because the $min$ operation together with the set of integers doesn't form a group, as there are no inverse elements. === "C++" - ```{.cpp file=fenwick_min} - struct FenwickTreeMin { - vector bit; - int n; - const int INF = (int)1e9; - - FenwickTreeMin(int n) { - this->n = n; - bit.assign(n, INF); - } +```{.cpp file=fenwick_min} +struct FenwickTreeMin { + vector bit; + int n; + const int INF = (int)1e9; - FenwickTreeMin(vector a) : FenwickTreeMin(a.size()) { - for (size_t i = 0; i < a.size(); i++) - update(i, a[i]); - } + FenwickTreeMin(int n) { + this->n = n; + bit.assign(n, INF); + } - int getmin(int r) { - int ret = INF; - for (; r >= 0; r = (r & (r + 1)) - 1) - ret = min(ret, bit[r]); - return ret; - } + FenwickTreeMin(vector a) : FenwickTreeMin(a.size()) { + for (size_t i = 0; i < a.size(); i++) + update(i, a[i]); + } - void update(int idx, int val) { - for (; idx < n; idx = idx | (idx + 1)) - bit[idx] = min(bit[idx], val); - } - }; - ``` + int getmin(int r) { + int ret = INF; + for (; r >= 0; r = (r & (r + 1)) - 1) + ret = min(ret, bit[r]); + return ret; + } + + void update(int idx, int val) { + for (; idx < n; idx = idx | (idx + 1)) + bit[idx] = min(bit[idx], val); + } +}; +``` === "Python" ```py class FenwickTreeMin: @@ -436,39 +436,39 @@ As you can see, the main benefit of this approach is that the binary operations The following implementation can be used like the other implementations, however it uses one-based indexing internally. === "C++" - ```{.cpp file=fenwick_sum_onebased} - struct FenwickTreeOneBasedIndexing { - vector bit; // binary indexed tree - int n; - - FenwickTreeOneBasedIndexing(int n) { - this->n = n + 1; - bit.assign(n + 1, 0); - } +```{.cpp file=fenwick_sum_onebased} +struct FenwickTreeOneBasedIndexing { + vector bit; // binary indexed tree + int n; - FenwickTreeOneBasedIndexing(vector a) - : FenwickTreeOneBasedIndexing(a.size()) { - for (size_t i = 0; i < a.size(); i++) - add(i, a[i]); - } + FenwickTreeOneBasedIndexing(int n) { + this->n = n + 1; + bit.assign(n + 1, 0); + } - int sum(int idx) { - int ret = 0; - for (++idx; idx > 0; idx -= idx & -idx) - ret += bit[idx]; - return ret; - } + FenwickTreeOneBasedIndexing(vector a) + : FenwickTreeOneBasedIndexing(a.size()) { + for (size_t i = 0; i < a.size(); i++) + add(i, a[i]); + } - int sum(int l, int r) { - return sum(r) - sum(l - 1); - } + int sum(int idx) { + int ret = 0; + for (++idx; idx > 0; idx -= idx & -idx) + ret += bit[idx]; + return ret; + } - void add(int idx, int delta) { - for (++idx; idx < n; idx += idx & -idx) - bit[idx] += delta; - } - }; - ``` + int sum(int l, int r) { + return sum(r) - sum(l - 1); + } + + void add(int idx, int delta) { + for (++idx; idx < n; idx += idx & -idx) + bit[idx] += delta; + } +}; +``` === "Python" ```py class FenwickTreeOneBasedIndexing: From 08b1de3464d197e80e42dc08b48e3ed619110089 Mon Sep 17 00:00:00 2001 From: Michael Hayter Date: Fri, 5 Dec 2025 23:27:49 -0800 Subject: [PATCH 17/20] Attempt update extract_snippets.py accepting spaces at beginning --- src/data_structures/fenwick.md | 180 ++++++++++++++++----------------- test/extract_snippets.py | 2 +- 2 files changed, 91 insertions(+), 91 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 296dfeefc..15af26c5f 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -166,36 +166,36 @@ You can create a Fenwick tree initialized with zeros, or you can convert an exis === "C++" ```{.cpp file=fenwick_sum} -struct FenwickTree { - vector bit; // binary indexed tree - int n; - - FenwickTree(int n) { - this->n = n; - bit.assign(n, 0); - } - - FenwickTree(vector const &a) : FenwickTree(a.size()) { - for (size_t i = 0; i < a.size(); i++) - add(i, a[i]); - } - - int sum(int r) { - int ret = 0; - for (; r >= 0; r = (r & (r + 1)) - 1) - ret += bit[r]; - return ret; - } - - int sum(int l, int r) { - return sum(r) - sum(l - 1); - } - - void add(int idx, int delta) { - for (; idx < n; idx = idx | (idx + 1)) - bit[idx] += delta; - } -}; + struct FenwickTree { + vector bit; // binary indexed tree + int n; + + FenwickTree(int n) { + this->n = n; + bit.assign(n, 0); + } + + FenwickTree(vector const &a) : FenwickTree(a.size()) { + for (size_t i = 0; i < a.size(); i++) + add(i, a[i]); + } + + int sum(int r) { + int ret = 0; + for (; r >= 0; r = (r & (r + 1)) - 1) + ret += bit[r]; + return ret; + } + + int sum(int l, int r) { + return sum(r) - sum(l - 1); + } + + void add(int idx, int delta) { + for (; idx < n; idx = idx | (idx + 1)) + bit[idx] += delta; + } + }; ``` === "Python" ```py @@ -254,33 +254,33 @@ Both significant limitations are because the $min$ operation together with the s === "C++" ```{.cpp file=fenwick_min} -struct FenwickTreeMin { - vector bit; - int n; - const int INF = (int)1e9; - - FenwickTreeMin(int n) { - this->n = n; - bit.assign(n, INF); - } - - FenwickTreeMin(vector a) : FenwickTreeMin(a.size()) { - for (size_t i = 0; i < a.size(); i++) - update(i, a[i]); - } - - int getmin(int r) { - int ret = INF; - for (; r >= 0; r = (r & (r + 1)) - 1) - ret = min(ret, bit[r]); - return ret; - } - - void update(int idx, int val) { - for (; idx < n; idx = idx | (idx + 1)) - bit[idx] = min(bit[idx], val); - } -}; + struct FenwickTreeMin { + vector bit; + int n; + const int INF = (int)1e9; + + FenwickTreeMin(int n) { + this->n = n; + bit.assign(n, INF); + } + + FenwickTreeMin(vector a) : FenwickTreeMin(a.size()) { + for (size_t i = 0; i < a.size(); i++) + update(i, a[i]); + } + + int getmin(int r) { + int ret = INF; + for (; r >= 0; r = (r & (r + 1)) - 1) + ret = min(ret, bit[r]); + return ret; + } + + void update(int idx, int val) { + for (; idx < n; idx = idx | (idx + 1)) + bit[idx] = min(bit[idx], val); + } + }; ``` === "Python" ```py @@ -436,39 +436,39 @@ As you can see, the main benefit of this approach is that the binary operations The following implementation can be used like the other implementations, however it uses one-based indexing internally. === "C++" -```{.cpp file=fenwick_sum_onebased} -struct FenwickTreeOneBasedIndexing { - vector bit; // binary indexed tree - int n; - - FenwickTreeOneBasedIndexing(int n) { - this->n = n + 1; - bit.assign(n + 1, 0); - } - - FenwickTreeOneBasedIndexing(vector a) - : FenwickTreeOneBasedIndexing(a.size()) { - for (size_t i = 0; i < a.size(); i++) - add(i, a[i]); - } - - int sum(int idx) { - int ret = 0; - for (++idx; idx > 0; idx -= idx & -idx) - ret += bit[idx]; - return ret; - } - - int sum(int l, int r) { - return sum(r) - sum(l - 1); - } - - void add(int idx, int delta) { - for (++idx; idx < n; idx += idx & -idx) - bit[idx] += delta; - } -}; -``` + ```{.cpp file=fenwick_sum_onebased} + struct FenwickTreeOneBasedIndexing { + vector bit; // binary indexed tree + int n; + + FenwickTreeOneBasedIndexing(int n) { + this->n = n + 1; + bit.assign(n + 1, 0); + } + + FenwickTreeOneBasedIndexing(vector a) + : FenwickTreeOneBasedIndexing(a.size()) { + for (size_t i = 0; i < a.size(); i++) + add(i, a[i]); + } + + int sum(int idx) { + int ret = 0; + for (++idx; idx > 0; idx -= idx & -idx) + ret += bit[idx]; + return ret; + } + + int sum(int l, int r) { + return sum(r) - sum(l - 1); + } + + void add(int idx, int delta) { + for (++idx; idx < n; idx += idx & -idx) + bit[idx] += delta; + } + }; + ``` === "Python" ```py class FenwickTreeOneBasedIndexing: diff --git a/test/extract_snippets.py b/test/extract_snippets.py index 69e796678..e28d73b31 100755 --- a/test/extract_snippets.py +++ b/test/extract_snippets.py @@ -12,7 +12,7 @@ def extract_tests(filepath): filepath_short = os.path.basename(filepath) article_name = filepath_short.split('.')[0] - snippet_start = re.compile(r"^```\{.cpp\s+file=(\S+)\}$") + snippet_start = re.compile(r"^\s*```\{.cpp\s+file=(\S+)\}$") snippet_end = re.compile(r"^```$") with open(filepath) as f: From 8259ac51f85cdb4b2e755a3a2b634047fdef4f05 Mon Sep 17 00:00:00 2001 From: Michael Hayter Date: Sat, 6 Dec 2025 00:13:58 -0800 Subject: [PATCH 18/20] tolerate space before end --- test/extract_snippets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/extract_snippets.py b/test/extract_snippets.py index e28d73b31..b8360f1a1 100755 --- a/test/extract_snippets.py +++ b/test/extract_snippets.py @@ -13,7 +13,7 @@ def extract_tests(filepath): article_name = filepath_short.split('.')[0] snippet_start = re.compile(r"^\s*```\{.cpp\s+file=(\S+)\}$") - snippet_end = re.compile(r"^```$") + snippet_end = re.compile(r"^\s*```$") with open(filepath) as f: in_snippet = False; From cbd2669a199870548e0f7ee46f02d5cded51fc07 Mon Sep 17 00:00:00 2001 From: Michael Hayter Date: Sat, 6 Dec 2025 01:09:51 -0800 Subject: [PATCH 19/20] This works locally. --- src/data_structures/fenwick.md | 122 ++++++++++++++++----------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 15af26c5f..765a93ba5 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -165,38 +165,38 @@ Also this implementation supports two constructors. You can create a Fenwick tree initialized with zeros, or you can convert an existing array into the Fenwick form. === "C++" -```{.cpp file=fenwick_sum} - struct FenwickTree { - vector bit; // binary indexed tree - int n; - - FenwickTree(int n) { - this->n = n; - bit.assign(n, 0); - } - - FenwickTree(vector const &a) : FenwickTree(a.size()) { - for (size_t i = 0; i < a.size(); i++) - add(i, a[i]); - } - - int sum(int r) { - int ret = 0; - for (; r >= 0; r = (r & (r + 1)) - 1) - ret += bit[r]; - return ret; - } - - int sum(int l, int r) { - return sum(r) - sum(l - 1); - } - - void add(int idx, int delta) { - for (; idx < n; idx = idx | (idx + 1)) - bit[idx] += delta; - } - }; -``` + ```{.cpp file=fenwick_sum} + struct FenwickTree { + vector bit; // binary indexed tree + int n; + + FenwickTree(int n) { + this->n = n; + bit.assign(n, 0); + } + + FenwickTree(vector const &a) : FenwickTree(a.size()) { + for (size_t i = 0; i < a.size(); i++) + add(i, a[i]); + } + + int sum(int r) { + int ret = 0; + for (; r >= 0; r = (r & (r + 1)) - 1) + ret += bit[r]; + return ret; + } + + int sum(int l, int r) { + return sum(r) - sum(l - 1); + } + + void add(int idx, int delta) { + for (; idx < n; idx = idx | (idx + 1)) + bit[idx] += delta; + } + }; + ``` === "Python" ```py class FenwickTree: @@ -253,35 +253,35 @@ Additionally, each time a value is `update`'d, the new value has to be smaller t Both significant limitations are because the $min$ operation together with the set of integers doesn't form a group, as there are no inverse elements. === "C++" -```{.cpp file=fenwick_min} - struct FenwickTreeMin { - vector bit; - int n; - const int INF = (int)1e9; - - FenwickTreeMin(int n) { - this->n = n; - bit.assign(n, INF); - } - - FenwickTreeMin(vector a) : FenwickTreeMin(a.size()) { - for (size_t i = 0; i < a.size(); i++) - update(i, a[i]); - } - - int getmin(int r) { - int ret = INF; - for (; r >= 0; r = (r & (r + 1)) - 1) - ret = min(ret, bit[r]); - return ret; - } - - void update(int idx, int val) { - for (; idx < n; idx = idx | (idx + 1)) - bit[idx] = min(bit[idx], val); - } - }; -``` + ```{.cpp file=fenwick_min} + struct FenwickTreeMin { + vector bit; + int n; + const int INF = (int)1e9; + + FenwickTreeMin(int n) { + this->n = n; + bit.assign(n, INF); + } + + FenwickTreeMin(vector a) : FenwickTreeMin(a.size()) { + for (size_t i = 0; i < a.size(); i++) + update(i, a[i]); + } + + int getmin(int r) { + int ret = INF; + for (; r >= 0; r = (r & (r + 1)) - 1) + ret = min(ret, bit[r]); + return ret; + } + + void update(int idx, int val) { + for (; idx < n; idx = idx | (idx + 1)) + bit[idx] = min(bit[idx], val); + } + }; + ``` === "Python" ```py class FenwickTreeMin: From 5b814d83434eec1c60976175c8ff803b40a0520a Mon Sep 17 00:00:00 2001 From: Michael Hayter Date: Sat, 6 Dec 2025 01:38:49 -0800 Subject: [PATCH 20/20] Update fenwick.md --- src/data_structures/fenwick.md | 168 ++++++++++++++++----------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/src/data_structures/fenwick.md b/src/data_structures/fenwick.md index 765a93ba5..a0ff48d16 100644 --- a/src/data_structures/fenwick.md +++ b/src/data_structures/fenwick.md @@ -167,34 +167,34 @@ You can create a Fenwick tree initialized with zeros, or you can convert an exis === "C++" ```{.cpp file=fenwick_sum} struct FenwickTree { - vector bit; // binary indexed tree - int n; - - FenwickTree(int n) { - this->n = n; - bit.assign(n, 0); - } - - FenwickTree(vector const &a) : FenwickTree(a.size()) { - for (size_t i = 0; i < a.size(); i++) - add(i, a[i]); - } - - int sum(int r) { - int ret = 0; - for (; r >= 0; r = (r & (r + 1)) - 1) - ret += bit[r]; - return ret; - } - - int sum(int l, int r) { - return sum(r) - sum(l - 1); - } - - void add(int idx, int delta) { - for (; idx < n; idx = idx | (idx + 1)) - bit[idx] += delta; - } + vector bit; // binary indexed tree + int n; + + FenwickTree(int n) { + this->n = n; + bit.assign(n, 0); + } + + FenwickTree(vector const &a) : FenwickTree(a.size()) { + for (size_t i = 0; i < a.size(); i++) + add(i, a[i]); + } + + int sum(int r) { + int ret = 0; + for (; r >= 0; r = (r & (r + 1)) - 1) + ret += bit[r]; + return ret; + } + + int sum(int l, int r) { + return sum(r) - sum(l - 1); + } + + void add(int idx, int delta) { + for (; idx < n; idx = idx | (idx + 1)) + bit[idx] += delta; + } }; ``` === "Python" @@ -255,31 +255,31 @@ Both significant limitations are because the $min$ operation together with the s === "C++" ```{.cpp file=fenwick_min} struct FenwickTreeMin { - vector bit; - int n; - const int INF = (int)1e9; - - FenwickTreeMin(int n) { - this->n = n; - bit.assign(n, INF); - } - - FenwickTreeMin(vector a) : FenwickTreeMin(a.size()) { - for (size_t i = 0; i < a.size(); i++) - update(i, a[i]); - } - - int getmin(int r) { - int ret = INF; - for (; r >= 0; r = (r & (r + 1)) - 1) - ret = min(ret, bit[r]); - return ret; - } - - void update(int idx, int val) { - for (; idx < n; idx = idx | (idx + 1)) - bit[idx] = min(bit[idx], val); - } + vector bit; + int n; + const int INF = (int)1e9; + + FenwickTreeMin(int n) { + this->n = n; + bit.assign(n, INF); + } + + FenwickTreeMin(vector a) : FenwickTreeMin(a.size()) { + for (size_t i = 0; i < a.size(); i++) + update(i, a[i]); + } + + int getmin(int r) { + int ret = INF; + for (; r >= 0; r = (r & (r + 1)) - 1) + ret = min(ret, bit[r]); + return ret; + } + + void update(int idx, int val) { + for (; idx < n; idx = idx | (idx + 1)) + bit[idx] = min(bit[idx], val); + } }; ``` === "Python" @@ -348,7 +348,7 @@ As claimed before, it is very easy to implement Fenwick Tree for multidimensiona === "Python" ```py class FenwickTree2D: - + def __init__(self, n: int, m: int) -> None: self.n = n self.m = m @@ -438,41 +438,41 @@ The following implementation can be used like the other implementations, however === "C++" ```{.cpp file=fenwick_sum_onebased} struct FenwickTreeOneBasedIndexing { - vector bit; // binary indexed tree - int n; - - FenwickTreeOneBasedIndexing(int n) { - this->n = n + 1; - bit.assign(n + 1, 0); - } - - FenwickTreeOneBasedIndexing(vector a) - : FenwickTreeOneBasedIndexing(a.size()) { - for (size_t i = 0; i < a.size(); i++) - add(i, a[i]); - } - - int sum(int idx) { - int ret = 0; - for (++idx; idx > 0; idx -= idx & -idx) - ret += bit[idx]; - return ret; - } - - int sum(int l, int r) { - return sum(r) - sum(l - 1); - } - - void add(int idx, int delta) { - for (++idx; idx < n; idx += idx & -idx) - bit[idx] += delta; - } + vector bit; // binary indexed tree + int n; + + FenwickTreeOneBasedIndexing(int n) { + this->n = n + 1; + bit.assign(n + 1, 0); + } + + FenwickTreeOneBasedIndexing(vector a) + : FenwickTreeOneBasedIndexing(a.size()) { + for (size_t i = 0; i < a.size(); i++) + add(i, a[i]); + } + + int sum(int idx) { + int ret = 0; + for (++idx; idx > 0; idx -= idx & -idx) + ret += bit[idx]; + return ret; + } + + int sum(int l, int r) { + return sum(r) - sum(l - 1); + } + + void add(int idx, int delta) { + for (++idx; idx < n; idx += idx & -idx) + bit[idx] += delta; + } }; ``` === "Python" ```py class FenwickTreeOneBasedIndexing: - + def __init__(self, a: Union[int, List[int]]) -> None: if isinstance(a, int): self.n = a + 1