Skip to content

Commit 377ae9a

Browse files
authored
Merge pull request #45 from ondrahb/fenwick-changes
Improvements to fenwick tree article
2 parents 6e962dc + 0e0c713 commit 377ae9a

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

src/data_structures/fenwick.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ Fenwick tree is a data structure which:
1515
1616
The most common application of Fenwick tree is _calculating the sum of a range_ (i.e. $f(A_1, A_2, \dots, A_k) = A_1 + A_2 + \dots + A_k$).
1717

18-
Fenwick tree was first described in the paper titled "A new data structure for cumulative frequency tables" (Peter M. Fenwick, 1994).
18+
Fenwick tree was first described in a paper titled "A new data structure for cumulative frequency tables" (Peter M. Fenwick, 1994).
1919

2020
### Description
2121

22-
For the sake of simplicity, we will assume that function $f$ is just *sum function*.
22+
For the sake of simplicity, we will assume that function $f$ is just a *sum function*.
2323

2424
Given an array of integers $A[0 \dots N-1]$. Fenwick tree is an array $T[0 \dots N-1]$, where each of its elements is equal to the sum of elements of $A$ in some range $[g(i); i]$:
2525

2626
$$T_i = \sum_{j = g(i)}^{i}{A_j}$$
2727

28-
where $g$ is some function that satisfies $(g(i) \le i)$, and we will define it a bit later.
28+
where $g$ is some function that satisfies $(g(i) \le i)$ and we will define it a bit later.
2929

3030
> **Note:** Fenwick tree presented here **does support** 0-based indexing (in case you were told that it does not support it).
3131
@@ -46,29 +46,29 @@ def inc (int i, int delta):
4646

4747
The function `sum` works as follows:
4848

49-
1. firstly, it adds the sum of the range $[g(r); r]$ (i.e. $T[r]$) to the `result` ;
50-
2. then, it "jumps" to the range $[g(g(r)-1); g(r)-1]$, and adds this range's sum to the `result` ;
51-
3. and so on, till it "jumps" from $[0; g(g( \dots g(r)-1 \dots -1)-1)]$ to $[g(-1); -1]$; that is where the `sum` stops jumping.
49+
1. first, it adds the sum of the range $[g(r); r]$ (i.e. $T[r]$) to the `result`
50+
2. then, it "jumps" to the range $[g(g(r)-1); g(r)-1]$, and adds this range's sum to the `result`
51+
3. and so on, until it "jumps" from $[0; g(g( \dots g(r)-1 \dots -1)-1)]$ to $[g(-1); -1]$; that is where the `sum` function stops jumping.
5252

5353
The function `inc` works with the same analogy, but "jumps" in the direction of increasing indices:
5454

5555
1. sums of the ranges $[g(j); j]$ that satisfy the condition $g(j) \le i \le j$ are increased by `delta` , that is `t[j] += delta` .
5656

57-
It is obvious that complexity of both `sum` and `upd` do depend on the function $g$. We will define the function $g$ in such a way, so that, both of the operations will have logarithmic complexity $O(lg N)$.
57+
It is obvious that complexity of both `sum` and `upd` do depend on the function $g$. We will define the function $g$ in such a way that both of the operations have a logarithmic complexity $O(lg N)$.
5858

59-
**Definition of $g(i)$.** Let us consider the least significant digit of $i$ in binary. If this digit is $0$, then let $g(i) = i$. Otherwise, if we examine digits of $i$ in binary (in decreasing order of significance), then $i$ should end with one or more $1$'s. We convert these $1$'s to $0$'s and assign the new number as the value of $g(i)$.
59+
**Definition of $g(i)$.** Let us consider the least significant digit of $i$ in binary. If this digit is $0$, then let $g(i) = i$. Otherwise, the binary representation of $i$ will end with at least one $1$ bit. We will flip all these tailing $1$'s (so they become $0$'s) and define the result as a value of $g(i)$.
6060

6161
There exists a trivial solution for the non-trivial operation described above:
6262

6363
```
6464
g(i) = i & (i+1)
6565
```
6666

67-
where `&` is logical AND operator. It is not hard to convince yourself that this solution does the same thing as the operation described above.
67+
where `&` is a logical AND operator. It is not hard to convince yourself that this solution does the same thing as the operation described above.
6868

69-
Now, we need to find a way to find all such $j$'s, so that, *g(j) <= i <= j*.
69+
Now, we need to find a way to find all $j$'s, such that *g(j) <= i <= j*.
7070

71-
It is easy to see that we can find all such $j$'s, by starting with $i$ and replacing the least significant one of all $0$'s with a $1$. For example, for $i = 10$ we have:
71+
It is easy to see that we can find all such $j$'s by starting with $i$ and flipping the least significant zero bit. For example, for $i = 10$ we have:
7272

7373
```
7474
j = 10, binary 0001010
@@ -79,13 +79,13 @@ j = 63, binary 0111111
7979
...
8080
```
8181

82-
Not surprisingly, there also exists a simple way to do the above operation:
82+
Unsurprisingly, there also exists a simple way to do the above operation:
8383

8484
```
8585
h(j) = j | (j+1)
8686
```
8787

88-
where `|` is the logical OR operator.
88+
where `|` is a logical OR operator.
8989

9090
### Implementation: finding sum in one-dimensional array
9191

@@ -121,7 +121,7 @@ struct FenwickTree {
121121

122122
### Implementation: finding minimum of $[0; r]$ in one-dimensional array
123123

124-
It is obvious that there is no way of finding minimum of range $[l; r]$ using Fenwick tree, as Fenwick tree can only answer the queries of type [0; r]. Additionally, each time a value is `update`'d, new value should be smaller than the current value (because, the $min$ function is not reversible). These, of course, are significant limitations.
124+
It is obvious that there is no way of finding minimum of range $[l; r]$ using Fenwick tree, as Fenwick tree can only answer queries of type [0; r]. Additionally, each time a value is `update`'d, new value should be smaller than the current value (because, the $min$ function is not reversible). These, of course, are significant limitations.
125125

126126
```cpp
127127
struct FenwickTreeMin {

0 commit comments

Comments
 (0)