Skip to content

Commit 0af04ec

Browse files
committed
merge with main
2 parents d41258a + 572eae6 commit 0af04ec

23 files changed

+526
-166
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Compiled pages are published at [https://cp-algorithms.com/](https://cp-algorith
2626

2727
### New articles
2828

29+
- (8 June 2024) [Knapsack Problem](https://cp-algorithms.com/dynamic_programming/knapsack.html)
2930
- (28 January 2024) [Introduction to Dynamic Programming](https://cp-algorithms.com/dynamic_programming/intro-to-dp.html)
3031
- (8 December 2023) [Hungarian Algorithm](https://cp-algorithms.com/graph/hungarian-algorithm.html)
3132
- (10 September 2023) [Tortoise and Hare Algorithm](https://cp-algorithms.com/others/tortoise_and_hare.html)

mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ edit_uri: edit/master/src/
3232
copyright: Text is available under the <a href="https://github.com/cp-algorithms/cp-algorithms/blob/master/LICENSE">Creative Commons Attribution Share Alike 4.0 International</a> License<br/>Copyright &copy; 2014 - 2024 by <a href="https://github.com/cp-algorithms/cp-algorithms/graphs/contributors">cp-algorithms contributors</a>
3333
extra_javascript:
3434
- javascript/config.js
35-
- https://polyfill.io/v3/polyfill.min.js?features=es6
35+
- https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6
3636
- https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js
3737
extra_css:
3838
- stylesheets/extra.css

src/algebra/bit-manipulation.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,44 @@ int countSetBits(int n)
186186
}
187187
```
188188
189+
### Count set bits upto $n$
190+
To count the number of set bits of all numbers upto the number $n$ (inclusive), we can run the Brian Kernighan's algorithm on all numbers upto $n$. But this will result in a "Time Limit Exceeded" in contest submissions.
191+
192+
We can use the fact that for numbers upto $2^x$ (i.e. from $1$ to $2^x - 1$) there are $x \cdot 2^{x-1}$ set bits. This can be visualised as follows.
193+
```
194+
0 -> 0 0 0 0
195+
1 -> 0 0 0 1
196+
2 -> 0 0 1 0
197+
3 -> 0 0 1 1
198+
4 -> 0 1 0 0
199+
5 -> 0 1 0 1
200+
6 -> 0 1 1 0
201+
7 -> 0 1 1 1
202+
8 -> 1 0 0 0
203+
```
204+
205+
We can see that the all the columns except the leftmost have $4$ (i.e. $2^2$) set bits each, i.e. upto the number $2^3 - 1$, the number of set bits is $3 \cdot 2^{3-1}$.
206+
207+
With the new knowledge in hand we can come up with the following algorithm:
208+
209+
- Find the highest power of $2$ that is lesser than or equal to the given number. Let this number be $x$.
210+
- Calculate the number of set bits from $1$ to $2^x - 1$ by using the formua $x \cdot 2^{x-1}$.
211+
- Count the no. of set bits in the most significant bit from $2^x$ to $n$ and add it.
212+
- Subtract $2^x$ from $n$ and repeat the above steps using the new $n$.
213+
214+
```cpp
215+
int countSetBits(int n) {
216+
int count = 0;
217+
while (n > 0) {
218+
int x = std::bit_width(n) - 1;
219+
count += x << (x - 1);
220+
n -= 1 << x;
221+
count += n + 1;
222+
}
223+
return count;
224+
}
225+
```
226+
189227
### Additional tricks
190228

191229
- $n ~\&~ (n + 1)$ clears all trailing ones: $0011~0111_2 \rightarrow 0011~0000_2$.

src/algebra/euclid-algorithm.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,4 @@ E.g. C++17 has such a function `std::gcd` in the `numeric` header.
126126
## Practice Problems
127127
128128
- [CSAcademy - Greatest Common Divisor](https://csacademy.com/contest/archive/task/gcd/)
129+
- [Codeforces 1916B - Two Divisors](https://codeforces.com/contest/1916/problem/B)

src/algebra/polynomial.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ Polynomial long division is useful because of its many important properties:
140140
Note that long division can't be properly defined for formal power series. Instead, for any $A(x)$ such that $a_0 \neq 0$, it is possible to define an inverse formal power series $A^{-1}(x)$, such that $A(x) A^{-1}(x) = 1$. This fact, in turn, can be used to compute the result of long division for polynomials.
141141

142142
## Basic implementation
143-
[Here](https://cp-algorithms.github.io/cp-algorithms-aux/cp-algo/algebra/poly.hpp) you can find the basic implementation of polynomial algebra.
143+
[Here](https://cp-algorithms.github.io/cp-algorithms-aux/cp-algo/math/poly.hpp) you can find the basic implementation of polynomial algebra.
144144

145145
It supports all trivial operations and some other useful methods. The main class is `poly<T>` for polynomials with coefficients of type `T`.
146146

src/combinatorics/bracket_sequences.md

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ We iterate over all character of the string, if the current bracket character is
3232
If at any time the variable $\text{depth}$ gets negative, or at the end it is different from $0$, then the string is not a balanced sequence.
3333
Otherwise it is.
3434

35-
If there are several bracket types involved, then the algorithm needs to be changes.
35+
If there are several bracket types involved, then the algorithm needs to be changed.
3636
Instead of a counter $\text{depth}$ we create a stack, in which we will store all opening brackets that we meet.
3737
If the current bracket character is an opening one, we put it onto the stack.
3838
If it is a closing one, then we check if the stack is non-empty, and if the top element of the stack is of the same type as the current closing bracket.
@@ -49,7 +49,7 @@ The number of balanced bracket sequences of length $2n$ ($n$ pairs of brackets)
4949

5050
$$\frac{1}{n+1} \binom{2n}{n}$$
5151

52-
If we allow $k$ types of brackets, then each pair be of any of the $k$ types (independently of the others), thus the number of balanced bracket sequences is:
52+
If we allow $k$ types of brackets, then each pair can be of any of the $k$ types (independently of the others), thus the number of balanced bracket sequences is:
5353

5454
$$\frac{1}{n+1} \binom{2n}{n} k^n$$
5555

@@ -82,7 +82,7 @@ When we meet an opening brackets, we will decrement $\text{depth}$, and when we
8282
If we are at some point meet an opening bracket, and the balance after processing this symbol is positive, then we have found the rightmost position that we can change.
8383
We change the symbol, compute the number of opening and closing brackets that we have to add to the right side, and arrange them in the lexicographically minimal way.
8484

85-
If we find do suitable position, then this sequence is already the maximal possible one, and there is no answer.
85+
If we don't find a suitable position, then this sequence is already the maximal possible one, and there is no answer.
8686

8787
```{.cpp file=next_balanced_brackets_sequence}
8888
bool next_balanced_sequence(string & s) {
@@ -117,7 +117,7 @@ To generate then, we can start with the lexicographically smallest sequence $((\
117117
118118
However, if the length of the sequence is not very long (e.g. $n$ smaller than $12$), then we can also generate all permutations conveniently with the C++ STL function `next_permutation`, and check each one for balanceness.
119119
120-
Also they can be generate using the ideas we used for counting all sequences with dynamic programming.
120+
Also they can be generated using the ideas we used for counting all sequences with dynamic programming.
121121
We will discuss the ideas in the next two sections.
122122
123123
## Sequence index
@@ -142,19 +142,19 @@ Thus we can compute this array in $O(n^2)$.
142142
Now let us generate the index for a given sequence.
143143
144144
First let there be only one type of brackets.
145-
We will us the counter $\text{depth}$ which tells us how nested we currently are, and iterate over the characters of the sequence.
145+
We will use the counter $\text{depth}$ which tells us how nested we currently are, and iterate over the characters of the sequence.
146146
If the current character $s[i]$ is equal to $($, then we increment $\text{depth}$.
147147
If the current character $s[i]$ is equal to $)$, then we must add $d[2n-i-1][\text{depth}+1]$ to the answer, taking all possible endings starting with a $($ into account (which are lexicographically smaller sequences), and then decrement $\text{depth}$.
148148
149149
New let there be $k$ different bracket types.
150150
151-
Thus, when we look at the current character $s[i]$ before recomputing $\text{depth}$, we have to go through all bracket types that are smaller than the current character, and try to put this bracket into the current position (obtaining a new balance $\text{ndepth} = \text{depth} \pm 1$), and add the number of ways to finish the sequence (length $2n-i-1$, balance $ndepth$) to the answer:
151+
Thus, when we look at the current character $s[i]$ before recomputing $\text{depth}$, we have to go through all bracket types that are smaller than the current character, and try to place this bracket into the current position (obtaining a new balance $\text{ndepth} = \text{depth} \pm 1$), and add the number of ways to finish the sequence (length $2n-i-1$, balance $ndepth$) to the answer:
152152
153153
$$d[2n - i - 1][\text{ndepth}] \cdot k^{\frac{2n - i - 1 - ndepth}{2}}$$
154154
155155
This formula can be derived as follows:
156156
First we "forget" that there are multiple bracket types, and just take the answer $d[2n - i - 1][\text{ndepth}]$.
157-
Now we consider how the answer will change is we have $k$ types of brackets.
157+
Now we consider how the answer will change if we have $k$ types of brackets.
158158
We have $2n - i - 1$ undefined positions, of which $\text{ndepth}$ are already predetermined because of the opening brackets.
159159
But all the other brackets ($(2n - i - 1 - \text{ndepth})/2$ pairs) can be of any type, therefore we multiply the number by such a power of $k$.
160160
@@ -169,10 +169,9 @@ First, we start with only one bracket type.
169169
170170
We will iterate over the characters in the string we want to generate.
171171
As in the previous problem we store a counter $\text{depth}$, the current nesting depth.
172-
In each position we have to decide if we use an opening of a closing bracket.
173-
To have to put an opening bracket character, it $d[2n - i - 1][\text{depth}+1] \ge k$.
174-
We increment the counter $\text{depth}$, and move on to the next character.
175-
Otherwise we decrement $k$ by $d[2n - i - 1][\text{depth}+1]$, put a closing bracket and move on.
172+
At each position, we have to decide whether to place an opening or a closing bracket. To place an opening bracket, $d[2n - i - 1][\text{depth}+1] \ge k$ must be true.
173+
If so, we increment the counter $\text{depth}$, and move on to the next character.
174+
Otherwise, we decrement $k$ by $d[2n - i - 1][\text{depth}+1]$, place a closing bracket, and move on.
176175
177176
```{.cpp file=kth_balances_bracket}
178177
string kth_balanced(int n, int k) {

src/data_structures/disjoint_set_union.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ If we add an edge $(a, b)$ that connects two connected components into one, then
375375
376376
Let's derive a formula, which computes the parity issued to the leader of the set that will get attached to another set.
377377
Let $x$ be the parity of the path length from vertex $a$ up to its leader $A$, and $y$ as the parity of the path length from vertex $b$ up to its leader $B$, and $t$ the desired parity that we have to assign to $B$ after the merge.
378-
The path contains the of the three parts:
378+
The path consists of the three parts:
379379
from $B$ to $b$, from $b$ to $a$, which is connected by one edge and therefore has parity $1$, and from $a$ to $A$.
380380
Therefore we receive the formula ($\oplus$ denotes the XOR operation):
381381

src/data_structures/fenwick.md

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,48 @@ e_maxx_link: fenwick_tree
66

77
# Fenwick Tree
88

9-
Let, $f$ be some group operation (binary associative function over a set with identity element and inverse elements) and $A$ be an array of integers of length $N$.
9+
Let $f$ be some group operation (a binary associative function over a set with an identity element and inverse elements) and $A$ be an array of integers of length $N$.
10+
Denote $f$'s infix notation as $*$; that is, $f(x,y) = x*y$ for arbitrary integers $x,y$.
11+
(Since this is associative, we will omit parentheses for order of application of $f$ when using infix notation.)
1012

11-
Fenwick tree is a data structure which:
13+
The Fenwick tree is a data structure which:
1214

13-
* calculates the value of function $f$ in the given range $[l, r]$ (i.e. $f(A_l, A_{l+1}, \dots, A_r)$) in $O(\log N)$ time;
14-
* updates the value of an element of $A$ in $O(\log N)$ time;
15-
* requires $O(N)$ memory, or in other words, exactly the same memory required for $A$;
16-
* is easy to use and code, especially, in the case of multidimensional arrays.
15+
* calculates the value of function $f$ in the given range $[l, r]$ (i.e. $A_l * A_{l+1} * \dots * A_r$) in $O(\log N)$ time
16+
* updates the value of an element of $A$ in $O(\log N)$ time
17+
* requires $O(N)$ memory (the same amount required for $A$)
18+
* is easy to use and code, especially in the case of multidimensional arrays
1719

18-
The most common application of Fenwick tree is _calculating the sum of a range_ (i.e. using addition over the set of integers $\mathbb{Z}$: $f(A_1, A_2, \dots, A_k) = A_1 + A_2 + \dots + A_k$).
20+
The most common application of a Fenwick tree is _calculating the sum of a range_.
21+
For example, using addition over the set of integers as the group operation, i.e. $f(x,y) = x + y$: the binary operation, $*$, is $+$ in this case, so $A_l * A_{l+1} * \dots * A_r = A_l + A_{l+1} + \dots + A_{r}$.
1922

20-
Fenwick tree is also called **Binary Indexed Tree**, or just **BIT** abbreviated.
21-
22-
Fenwick tree was first described in a paper titled "A new data structure for cumulative frequency tables" (Peter M. Fenwick, 1994).
23+
The Fenwick tree is also called a **Binary Indexed Tree** (BIT).
24+
It was first described in a paper titled "A new data structure for cumulative frequency tables" (Peter M. Fenwick, 1994).
2325

2426
## Description
2527

2628
### Overview
2729

28-
For the sake of simplicity, we will assume that function $f$ is just a *sum function*.
30+
For the sake of simplicity, we will assume that function $f$ is defined as $f(x,y) = x + y$ over the integers.
2931

30-
Given an array of integers $A[0 \dots N-1]$.
31-
A Fenwick tree is just 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]$:
32+
Suppose we are given an array of integers, $A[0 \dots N-1]$.
33+
(Note that we are using zero-based indexing.)
34+
A Fenwick tree is just an array, $T[0 \dots N-1]$, where each element is equal to the sum of elements of $A$ in some range, $[g(i), i]$:
3235

33-
$$T_i = \sum_{j = g(i)}^{i}{A_j},$$
36+
$$T_i = \sum_{j = g(i)}^{i}{A_j}$$
3437

3538
where $g$ is some function that satisfies $0 \le g(i) \le i$.
36-
We will define the function in the next few paragraphs.
39+
We will define $g$ in the next few paragraphs.
3740

38-
The data structure is called tree, because there is a nice representation of the data structure as tree, although we don't need to model an actual tree with nodes and edges.
39-
We will only need to maintain the array $T$ to handle all queries.
41+
The data structure is called a tree because there is a nice representation of it in the form of a tree, although we don't need to model an actual tree with nodes and edges.
42+
We only need to maintain the array $T$ to handle all queries.
4043

4144
**Note:** The Fenwick tree presented here uses zero-based indexing.
42-
Many people will actually use a version of the Fenwick tree that uses one-based indexing.
43-
Therefore you will also find an alternative implementation using one-based indexing in the implementation section.
45+
Many people use a version of the Fenwick tree that uses one-based indexing.
46+
As such, you will also find an alternative implementation which uses one-based indexing in the implementation section.
4447
Both versions are equivalent in terms of time and memory complexity.
4548

46-
Now we can write some pseudo-code for the two operations mentioned above - get the sum of elements of $A$ in the range $[0, r]$ and update (increase) some element $A_i$:
49+
Now we can write some pseudo-code for the two operations mentioned above.
50+
Below, we get the sum of elements of $A$ in the range $[0, r]$ and update (increase) some element $A_i$:
4751

4852
```python
4953
def sum(int r):
@@ -60,20 +64,21 @@ def increase(int i, int delta):
6064

6165
The function `sum` works as follows:
6266

63-
1. first, it adds the sum of the range $[g(r), r]$ (i.e. $T[r]$) to the `result`
64-
2. then, it "jumps" to the range $[g(g(r)-1), g(r)-1]$, and adds this range's sum to the `result`
65-
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.
67+
1. First, it adds the sum of the range $[g(r), r]$ (i.e. $T[r]$) to the `result`.
68+
2. Then, it "jumps" to the range $[g(g(r)-1), g(r)-1]$ and adds this range's sum to the `result`.
69+
3. This continues until it "jumps" from $[0, g(g( \dots g(r)-1 \dots -1)-1)]$ to $[g(-1), -1]$; this is where the `sum` function stops jumping.
6670

67-
The function `increase` works with the same analogy, but "jumps" in the direction of increasing indices:
71+
The function `increase` works with the same analogy, but it "jumps" in the direction of increasing indices:
6872

69-
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`. Therefore we updated all elements in $T$ that correspond to ranges in which $A_i$ lies.
73+
1. The sum for each range of the form $[g(j), j]$ which satisfies the condition $g(j) \le i \le j$ is increased by `delta`; that is, `t[j] += delta`.
74+
Therefore, it updates all elements in $T$ that correspond to ranges in which $A_i$ lies.
7075

71-
It is obvious that the complexity of both `sum` and `increase` depend on the function $g$.
72-
There are lots of ways to choose the function $g$, as long as $0 \le g(i) \le i$ for all $i$.
73-
For instance the function $g(i) = i$ works, which results just in $T = A$, and therefore summation queries are slow.
74-
We can also take the function $g(i) = 0$.
75-
This will correspond to prefix sum arrays, which means that finding the sum of the range $[0, i]$ will only take constant time, but updates are slow.
76-
The clever part of the Fenwick algorithm is, that there it uses a special definition of the function $g$ that can handle both operations in $O(\log N)$ time.
76+
The complexity of both `sum` and `increase` depend on the function $g$.
77+
There are many ways to choose the function $g$ such that $0 \le g(i) \le i$ for all $i$.
78+
For instance, the function $g(i) = i$ works, which yields $T = A$ (in which case, the summation queries are slow).
79+
We could also take the function $g(i) = 0$.
80+
This would correspond to prefix sum arrays (in which case, finding the sum of the range $[0, i]$ will only take constant time; however, updates are slow).
81+
The clever part of the algorithm for Fenwick trees is how it uses a special definition of the function $g$ which can handle both operations in $O(\log N)$ time.
7782

7883
### Definition of $g(i)$ { data-toc-label='Definition of <script type="math/tex">g(i)</script>' }
7984

@@ -380,7 +385,7 @@ int point_query(int idx) {
380385

381386
Note: of course it is also possible to increase a single point $A[i]$ with `range_add(i, i, val)`.
382387

383-
### 3. Range Updates and Range Queries
388+
### 3. Range Update and Range Query
384389

385390
To support both range updates and range queries we will use two BITs namely $B_1[]$ and $B_2[]$, initialized with zeros.
386391

0 commit comments

Comments
 (0)