Gold
This commit is contained in:
parent
7d4f88925b
commit
088d0260e1
|
@ -3,7 +3,7 @@ id: bfs
|
|||
title: "Breadth First Search (BFS)"
|
||||
author: Benjamin Qi, Michael Cao
|
||||
prerequisites:
|
||||
- Silver - Depth First Search
|
||||
- dfs
|
||||
description: "Traversing a graph in a way such that vertices closer to the starting vertex are processed first."
|
||||
frequency: 2
|
||||
---
|
||||
|
@ -33,7 +33,7 @@ export const metadata = {
|
|||
|
||||
<Resources>
|
||||
<Resource source="CSA" title="Breadth First Search" url="breadth_first_search" starred>interactive</Resource>
|
||||
<Resource source="CPH" title="12.2 - Breadth-First Search" starred></Resource>
|
||||
<Resource source="CPH" title="12.2 - Breadth-First Search"></Resource>
|
||||
<Resource source="PAPS" title="12.1 - Breadth-First Search"></Resource>
|
||||
<Resource source="KA" title="Breadth First Search and Its Uses" url="https://www.khanacademy.org/computing/computer-science/algorithms/breadth-first-search/a/breadth-first-search-and-its-uses"></Resource>
|
||||
<Resource source="cp-algo" title="Breadth First Search" url="graph/breadth-first-search.html"></Resource>
|
||||
|
@ -43,7 +43,70 @@ export const metadata = {
|
|||
|
||||
## Implementation
|
||||
|
||||
<IncompleteSection />
|
||||
<LanguageSection>
|
||||
|
||||
<CPPSection>
|
||||
|
||||
From the CSA article:
|
||||
|
||||
```cpp
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
using namespace std;
|
||||
const int MAX_N = 100005;
|
||||
|
||||
vector<int> graph[MAX_N];
|
||||
int dist[MAX_N];
|
||||
bool visited[MAX_N];
|
||||
|
||||
void bfs(int startNode) {
|
||||
dist[startNode] = 0;
|
||||
queue<int> bfsQueue;
|
||||
bfsQueue.push(startNode);
|
||||
visited[startNode] = true;
|
||||
while (!bfsQueue.empty()) {
|
||||
int currentNode = bfsQueue.front();
|
||||
bfsQueue.pop();
|
||||
for (auto neighbour: graph[currentNode]) {
|
||||
if (!visited[neighbour]) {
|
||||
visited[neighbour] = true;
|
||||
dist[neighbour] = dist[currentNode] + 1;
|
||||
bfsQueue.push(neighbour);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int N, M, v, x, y;
|
||||
cin >> N >> M >> v;
|
||||
for (int i = 1; i <= M; i += 1) {
|
||||
cin >> x >> y;
|
||||
graph[x].push_back(y);
|
||||
}
|
||||
for (int i = 1; i <= N; i += 1) {
|
||||
dist[i] = -1;
|
||||
}
|
||||
bfs(v);
|
||||
for (int i = 1; i <= N; i += 1) {
|
||||
cout << dist[i] << " ";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
</CPPSection>
|
||||
|
||||
<JavaSection>
|
||||
|
||||
|
||||
|
||||
</JavaSection>
|
||||
|
||||
</LanguageSection>
|
||||
|
||||
## Example: Cow Navigation
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ id: cyc
|
|||
title: Cycle Detection
|
||||
author: Siyong Huang
|
||||
prerequisites:
|
||||
- Gold - Topological Sort
|
||||
- toposort
|
||||
description: "A simple cycle is a non-empty path of distinct edges that start and end at the same vertex such that no vertex appears more than once. Describes how to detect cycles in both directed and undirected graphs."
|
||||
frequency: 0
|
||||
---
|
||||
|
|
|
@ -3,6 +3,7 @@ id: intro-dp
|
|||
title: "Introduction to Dynamic Programming"
|
||||
author: Michael Cao
|
||||
prerequisites:
|
||||
- complete-search
|
||||
- prefix-sums
|
||||
description: "Speeding up naive recursive solutions with memoization."
|
||||
frequency: 4
|
||||
|
@ -44,7 +45,8 @@ export const metadata = {
|
|||
new Problem("Old Gold", "Palindromic Paths", "553", "Hard", false, ["DP"], "start from the middle, dp[row i][row j][length] = number of strings of length 2 * length + 1 with ends at row i and j"),
|
||||
],
|
||||
lis: [
|
||||
new Problem("LC", "Longest Increasing Subsequence", "https://leetcode.com/problems/longest-increasing-subsequence/", "Easy", true, ["DP"], "dp[i] = LIS up to i, use binary search to decrease runtime from quadratic"),
|
||||
new Problem("LC", "Longest Increasing Subsequence", "https://leetcode.com/problems/longest-increasing-subsequence/", "Very Easy", true, ["DP"], "dp[i] = LIS up to i, use binary search to decrease runtime from quadratic"),
|
||||
new Problem("Kattis", "Longest Increasing Subsequence", "longincsubseq", "Easy", true, [], ""),
|
||||
new Problem("Old Gold", "Cowjog", "496", "Easy", false, ["DP"], "direct application of longest increasing subsequence"),
|
||||
new Problem("Plat", "Sort It Out", "865", "Very Hard", false, ["DP"], "component of kth largest LIS, read editorial for more details"),
|
||||
],
|
||||
|
@ -97,7 +99,7 @@ Interesting applications of "number of paths on a grid," some of which don't dir
|
|||
|
||||
## Longest Increasing Subsequence
|
||||
|
||||
The first problem requires a quadratic time complexity solution to Longset Increasing subsequence, but you should optimize it to $O(N \log N)$. Some of the problems in this section don't initially look like Longest Increasing Subsequence, but it ends up being the solution <Asterick>This can happen a lot, which is why it's a good idea to not focus on one topic unless you have a full solution</Asterick>.
|
||||
Some of the problems in this section don't initially look like Longest Increasing Subsequence, but it ends up being the solution. <Asterisk>This can happen a lot, which is why it's a good idea to not focus on one topic unless you have a full solution</Asterisk>
|
||||
|
||||
<Problems problems={metadata.problems.lis} />
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ id: dp-trees
|
|||
title: "Dynamic Programming on Trees"
|
||||
author: Michael Cao
|
||||
prerequisites:
|
||||
- Silver - Depth First Search
|
||||
- Gold - Introduction to Dynamic Programming
|
||||
- dfs
|
||||
- intro-dp
|
||||
description: "Using subtrees as subproblems."
|
||||
frequency: 1
|
||||
---
|
||||
|
@ -39,6 +39,8 @@ export const metadata = {
|
|||
<Resource source="Philippines" title="DP on Trees and DAGs" url="https://noi.ph/training/weekly/week5.pdf">lol this code format is terrible </Resource>
|
||||
</Resources>
|
||||
|
||||
## Sample Solution
|
||||
|
||||
## Solving for All Roots
|
||||
|
||||
<Problems problems={metadata.problems.allRoots} />
|
||||
|
|
|
@ -3,7 +3,7 @@ id: dsu
|
|||
title: "Disjoint Set Union"
|
||||
author: Benjamin Qi, Michael Cao
|
||||
prerequisites:
|
||||
- Silver - Depth First Search
|
||||
- dfs
|
||||
description: "The Disjoint Set Union (DSU) data structure allows you to add edges to an initially empty graph and test whether two vertices of the graph are connected."
|
||||
frequency: 3
|
||||
---
|
||||
|
@ -28,9 +28,9 @@ export const metadata = {
|
|||
|
||||
<Resources>
|
||||
<Resource source="CSA" title="Disjoint Data Sets" url="disjoint_data_sets" starred>both optimizations, diagrams</Resource>
|
||||
<Resource source="PAPS" title="11.1 - Disjoint Sets" starred>both optimizations, no diagrams</Resource>
|
||||
<Resource source="CPH" title="15.2 - Union-Find">small to large, diagrams</Resource>
|
||||
<Resource source="IUSACO" title="10.6 - Disjoint-Set Data Structure">path compression, diagrams</Resource>
|
||||
<Resource source="PAPS" title="11.1 - Disjoint Sets">both optimizations, no diagrams</Resource>
|
||||
<Resource source="TC" title="Disjoint Set Data Structures" url="disjoint-set-data-structures">diagrams</Resource>
|
||||
<Resource source="CPC" title="3 - Data Structures" url="03_data_structures"></Resource>
|
||||
</Resources>
|
||||
|
@ -46,7 +46,32 @@ Note: You may prefer to use this in place of DFS for computing connected compone
|
|||
|
||||
## Implementations
|
||||
|
||||
<IncompleteSection />
|
||||
Check PAPS for the explanation. `e[x]` contains the negation of the size of $x$'s component if $x$ is the representative of its component, and the parent of $x$ otherwise.
|
||||
|
||||
<LanguageSection>
|
||||
|
||||
<CPPSection>
|
||||
|
||||
<resource source="Benq (from KACTL)" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/graphs%20(12)/DSU/DSU%20(7.6).h"> </resource>
|
||||
|
||||
```cpp
|
||||
struct DSU {
|
||||
vi e; void init(int N) { e = vi(N,-1); }
|
||||
// get representive component, uses path compression
|
||||
int get(int x) { return e[x] < 0 ? x : e[x] = get(e[x]); }
|
||||
bool sameSet(int a, int b) { return get(a) == get(b); }
|
||||
int size(int x) { return -e[get(x)]; }
|
||||
bool unite(int x, int y) { // union by size
|
||||
x = get(x), y = get(y); if (x == y) return 0;
|
||||
if (e[x] > e[y]) swap(x,y);
|
||||
e[x] += e[y]; e[y] = x; return 1;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
</CPPSection>
|
||||
|
||||
</LanguageSection>
|
||||
|
||||
## Problems
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ author: Benjamin Qi
|
|||
description: "Introduces gp_hash_table."
|
||||
frequency: 1
|
||||
prerequisites:
|
||||
- Bronze - Unordered Maps & Sets
|
||||
- unordered
|
||||
---
|
||||
|
||||
import { Problem } from "../models";
|
||||
|
|
|
@ -4,6 +4,7 @@ title: "Introductory Number Theory"
|
|||
author: Darren Yao, Michael Cao
|
||||
prerequisites:
|
||||
- intro-dp
|
||||
- binary representation
|
||||
description: Introduces divisibility and modular arithmetic.
|
||||
frequency: 1
|
||||
---
|
||||
|
@ -31,6 +32,8 @@ export const metadata = {
|
|||
|
||||
<Resources>
|
||||
<Resource source="IUSACO" title="13 - Elementary Number Theory">module is based off this</Resource>
|
||||
<Resource source="AoPS" title="Alcumus" url="https://artofproblemsolving.com/alcumus/problem" starred>practice problems, set focus to number theory!</Resource>
|
||||
<Resource source="AoPS" title ="Intro to NT" url="https://artofproblemsolving.com/store/item/intro-number-theory?gtmlist=Bookstore_AoPS_Side">good book :D</Resource>
|
||||
<Resource source="CPH" title="21.1, 21.2 - Number Theory">primes and factors, modular arithmetic</Resource>
|
||||
<Resource source="PAPS" title="16 - Number Theory">same as below</Resource>
|
||||
<Resource source="CF" title="CodeNCode - Number Theory Course" url="blog/entry/77137">lots of advanced stuff you don't need to know at this level</Resource>
|
||||
|
@ -52,6 +55,12 @@ Now, we will discuss how to find the prime factorization of an integer.
|
|||
|
||||
![Pseudocode](factoralgorithm1.png)
|
||||
|
||||
<IncompleteSection>
|
||||
|
||||
replace with code in all langs?
|
||||
|
||||
</IncompleteSection>
|
||||
|
||||
This algorithm runs in $O(\sqrt{n})$ time, because the for loop checks divisibility for at most $\sqrt{n}$ values. Even though there is a while loop inside the for loop, dividing $n$ by $i$ quickly reduces the value of $n$, which means that the outer for loop runs less iterations, which actually speeds up the code.
|
||||
|
||||
Let's look at an example of how this algorithm works, for $n = 252$.
|
||||
|
@ -61,9 +70,9 @@ Let's look at an example of how this algorithm works, for $n = 252$.
|
|||
At this point, the for loop terminates, because $i$ is already 3 which is greater than $\lfloor \sqrt{7} \rfloor$. In the last step, we add $7$ to the list of factors $v$, because it otherwise won't be added, for a final prime factorization of $\{2, 2, 3, 3, 7\}$.
|
||||
|
||||
|
||||
## GCD & LCM
|
||||
## GCD
|
||||
|
||||
The **greatest common divisor (GCD)** of two integers $a$ and $b$ is the largest integer that is a factor of both $a$ and $b$. In order to find the GCD of two numbers, we use the Euclidean Algorithm, which is as follows:
|
||||
The **greatest common divisor (GCD)** of two integers $a$ and $b$ is the largest integer that is a factor of both $a$ and $b$. In order to find the GCD of two numbers, we use the **Euclidean Algorithm**, which is as follows:
|
||||
|
||||
$$
|
||||
\gcd(a, b) = \begin{cases}
|
||||
|
@ -80,25 +89,52 @@ This algorithm is very easy to implement using a recursive function, as follows:
|
|||
|
||||
```java
|
||||
public int gcd(int a, int b){
|
||||
if(b == 0) return a;
|
||||
if (b == 0) return a;
|
||||
return gcd(b, a % b);
|
||||
}
|
||||
```
|
||||
|
||||
</JavaSection>
|
||||
|
||||
<CPPSection>
|
||||
|
||||
```cpp
|
||||
int GCD(int a, int b){
|
||||
if (b == 0) return a;
|
||||
return GCD(b, a % b);
|
||||
}
|
||||
```
|
||||
|
||||
For C++14 and below, use the built-in `__gcd(a,b)`. C++17 has built in `gcd(a,b)`.
|
||||
|
||||
</CPPSection>
|
||||
|
||||
</LanguageSection>
|
||||
|
||||
For C++, use the built-in `__gcd(a,b)`. Finding the GCD of two numbers can be done in $O(\log n)$ time, where $n = \min(a, b)$.
|
||||
This function runs in $O(\log \max(a,b))$ time.
|
||||
|
||||
<IncompleteSection>
|
||||
|
||||
proof?
|
||||
|
||||
</IncompleteSection>
|
||||
|
||||
## LCM
|
||||
|
||||
The **least common multiple (LCM)** of two integers $a$ and $b$ is the smallest integer divisible by both $a$ and $b$.
|
||||
|
||||
The LCM can easily be calculated from the following property with the GCD:
|
||||
|
||||
$$
|
||||
\operatorname{lcm}(a, b) = \frac{a \cdot b}{\gcd(a, b)}.
|
||||
\operatorname{lcm}(a, b) = \frac{a \cdot b}{\gcd(a, b)}=\frac{a}{\gcd(a,b)}\cdot b.
|
||||
$$
|
||||
|
||||
<Warning>
|
||||
|
||||
Dividing by $\gcd(a,b)$ first might prevent integer overflow.
|
||||
|
||||
</Warning>
|
||||
|
||||
If we want to take the GCD or LCM of more than two elements, we can do so two at a time, in any order. For example,
|
||||
|
||||
$$
|
||||
|
@ -107,7 +143,11 @@ $$
|
|||
|
||||
## Modular Arithmetic
|
||||
|
||||
In **modular arithmetic**, instead of working with integers themselves, we work with their remainders when divided by $m$. We call this taking modulo $m$. For example, if we take $m = 23$, then instead of working with $x = 247$, we use $x \bmod 23 = 17$. Usually, $m$ will be a large prime, given in the problem; the two most common values are $10^9 + 7$, and $998\,244\,353$. Modular arithmetic is used to avoid dealing with numbers that overflow built-in data types, because we can take remainders, according to the following formulas:
|
||||
<Resources>
|
||||
<Resource source="David Altizio" title="Modular Arithmetic" url="https://davidaltizio.web.illinois.edu/ModularArithmetic.pdf" starred> </Resource>
|
||||
</Resources>
|
||||
|
||||
In **modular arithmetic**, instead of working with integers themselves, we work with their remainders when divided by $m$. We call this taking modulo $m$. For example, if we take $m = 23$, then instead of working with $x = 247$, we use $x \bmod 23 = 17$. Usually, $m$ will be a large prime, given in the problem; the two most common values are $10^9 + 7$, and $998\,244\,353=119\cdot 2^{23}+1$. Modular arithmetic is used to avoid dealing with numbers that overflow built-in data types, because we can take remainders, according to the following formulas:
|
||||
|
||||
$$
|
||||
(a+b) \bmod m = (a \bmod m + b \bmod m) \bmod m
|
||||
|
@ -127,7 +167,9 @@ $$
|
|||
|
||||
## Modular Exponentiation
|
||||
|
||||
Under a **prime** modulus, division can be performed using modular inverses.
|
||||
<Resources>
|
||||
<Resource source="cp-algo" title="Binary Exponentiation" url="algebra/binary-exp.html"> </Resource>
|
||||
</Resources>
|
||||
|
||||
**Modular Exponentiation** can be used to efficently compute $x ^ n \mod m$. To do this, let's break down $x ^ n$ into binary components. For example, $5 ^ {10}$ = $5 ^ {1010_2}$ = $5 ^ 8 \cdot 5 ^ 4$. Then, if we know $x ^ y$ for all $y$ which are powers of two ($x ^ 1$, $x ^ 2$, $x ^ 4$, $\dots$ , $x ^ {2^{\lfloor{\log_2n} \rfloor}}$, we can compute $x ^ n$ in $\mathcal{O}(\log n)$. Finally, since $x ^ y$ for some $y \neq 1$ equals $2 \cdot x ^ {y - 1}$, and $x$ otherwise, we can compute these sums efficently. To deal with $m$, observe that modulo doesn't affect multiplications, so we can directly implement the above "binary exponentiation" algorithm while adding a line to take results $\pmod m$.
|
||||
|
||||
|
@ -155,10 +197,12 @@ long long binpow(long long x, long long n, long long m) {
|
|||
|
||||
</LanguageSection>
|
||||
|
||||
## Modular Inverse (Prime Moduli)
|
||||
## Modular Inverse
|
||||
|
||||
We'll only consider **prime** moduli here. Division can be performed using modular inverses.
|
||||
|
||||
<Resources>
|
||||
<Resource source="CP-Algorithms" title="Modular Multiplicative Inverse" url="https://cp-algorithms.com/algebra/module-inverse.html">Various ways to take modular inverse</Resource>
|
||||
<Resource source="cp-algo" title="Modular Multiplicative Inverse" url="algebra/module-inverse.html">Various ways to take modular inverse</Resource>
|
||||
</Resources>
|
||||
|
||||
### With Exponentiation
|
||||
|
@ -177,7 +221,7 @@ Also, one must always ensure that they do not attempt to divide by 0. Be aware t
|
|||
|
||||
<Optional>
|
||||
|
||||
See [this module](../adv/extend-euclid).
|
||||
See the module in the [Advanced](../adv/extend-euclid) section.
|
||||
|
||||
</Optional>
|
||||
|
||||
|
|
|
@ -27,8 +27,6 @@ export const metadata = {
|
|||
}
|
||||
};
|
||||
|
||||
## Sample
|
||||
|
||||
<Problems problems={metadata.problems.standard} />
|
||||
|
||||
## Resources
|
||||
|
@ -41,6 +39,13 @@ export const metadata = {
|
|||
<Resource source="cp-algo" title="Kruskal's with DSU" url="graph/mst_kruskal_with_dsu.html"></Resource>
|
||||
</Resources>
|
||||
|
||||
## Implementation
|
||||
|
||||
### Kruskal's
|
||||
|
||||
### Prim's
|
||||
|
||||
|
||||
## USACO Problems
|
||||
|
||||
<Problems problems={metadata.problems.general} />
|
||||
|
|
|
@ -3,7 +3,7 @@ id: PURS
|
|||
title: "Point Update Range Sum"
|
||||
author: Benjamin Qi
|
||||
prerequisites:
|
||||
- Silver - Prefix Sums
|
||||
- prefix-sums
|
||||
description: "Introducing Segment Trees, Binary Indexed Trees, and Indexed Sets (C++ only)."
|
||||
frequency: 3
|
||||
---
|
||||
|
@ -55,7 +55,7 @@ Most gold range query problems require you to support following tasks in $O(\log
|
|||
- Update the element at a single position (point).
|
||||
- Query the sum of some consecutive subarray.
|
||||
|
||||
Both **segment tree*s* and **binary indexed trees** can accomplish this.
|
||||
Both **segment trees** and **binary indexed trees** can accomplish this.
|
||||
|
||||
## Segment Tree
|
||||
|
||||
|
@ -128,14 +128,19 @@ Implementation is shorter than segment tree, but maybe more confusing at first g
|
|||
|
||||
### Implementations
|
||||
|
||||
<LanguageSection>
|
||||
|
||||
<CPPSection>
|
||||
|
||||
<Resources>
|
||||
<Resource source="CF" title="mouse_wireless - Multi-dimensional BITs with Templates" url="https://codeforces.com/blog/entry/64914" starred></Resource>
|
||||
<Resource source="Benq" title="BIT" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/1D%20Range%20Queries%20(9.2)/BIT%20(9.2).h">based off above</Resource>
|
||||
</Resources>
|
||||
|
||||
(implementation)
|
||||
</CPPSection>
|
||||
|
||||
</LanguageSection>
|
||||
|
||||
<IncompleteSection />
|
||||
|
||||
## Finding $k$-th Element
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ id: sp
|
|||
title: "Shortest Paths with Non-Negative Edge Weights"
|
||||
author: Benjamin Qi
|
||||
prerequisites:
|
||||
- Gold - Breadth First Search
|
||||
- bfs
|
||||
description: "Introduces Dijkstra's Algorithm for a single source shortest path as well as Floyd-Warshall for All-Pairs Shortest Path."
|
||||
frequency: 3
|
||||
---
|
||||
|
|
|
@ -5,6 +5,7 @@ author: Benjamin Qi
|
|||
description: "Range queries for any associative operation over a static array."
|
||||
frequency: 1
|
||||
---
|
||||
|
||||
import { Problem } from "../models";
|
||||
|
||||
export const metadata = {
|
||||
|
|
|
@ -3,8 +3,7 @@ id: springboards
|
|||
title: "Max Suffix Query with Insertions Only"
|
||||
author: Benjamin Qi
|
||||
prerequisites:
|
||||
- Silver - More with Maps & Sets
|
||||
- Silver - Amortized Analysis
|
||||
- harder-ordered
|
||||
description: "A solution to USACO Gold - Springboards."
|
||||
frequency: 1
|
||||
---
|
||||
|
|
|
@ -4,6 +4,8 @@ title: "String Hashing"
|
|||
author: Benjamin Qi
|
||||
description: "Quickly test equality of substrings with a small probability of failure."
|
||||
frequency: 1
|
||||
prerequisites:
|
||||
- intro-nt
|
||||
---
|
||||
|
||||
import { Problem } from "../models";
|
||||
|
|
|
@ -76,6 +76,7 @@ export const sourceTooltip = {
|
|||
LC: 'LeetCode',
|
||||
POI: 'Polish Olympiad in Informatics',
|
||||
SO: 'StackOverflow',
|
||||
KA: 'KhanAcademy',
|
||||
'Old Bronze': 'USACO Platinum did not exist prior to 2015-16.',
|
||||
'Old Silver': 'USACO Platinum did not exist prior to 2015-16.',
|
||||
'Old Gold': 'USACO Platinum did not exist prior to 2015-16.',
|
||||
|
|
Reference in a new issue