add some more blocks

This commit is contained in:
Benjamin Qi 2020-07-14 14:38:28 -04:00
parent c0cc5c8552
commit 583c521893
15 changed files with 122 additions and 31 deletions

View file

@ -25,12 +25,6 @@ export const metadata = {
}
};
<info-block title="Pro Tip">
No silver problem should require BFS rather than DFS, but it's still good to know at this level.
</info-block>
## Sample
<problems-list problems={metadata.problems.sample} />
## Resources
@ -45,6 +39,10 @@ No silver problem should require BFS rather than DFS, but it's still good to kno
<resource source="IUSACO" title="10.4 - Graph Traversal Algorithms"></resource>
</resources>
## Implementation
<IncompleteSection />
## Problems
<problems-list problems={metadata.problems.general} />

View file

@ -45,6 +45,10 @@ An algorithm known as **BFS-Cycle** returns an integer that is at most one more
The same general idea is implemented below to find any cycle in a directed graph (if one exists). Note that this is almost identical to the DFS algorithm for topological sorting.
<LanguageSection>
<CPPSection>
```cpp
//UNTESTED
@ -89,6 +93,18 @@ int main()
}
```
</CPPSection>
<JavaSection>
</JavaSection>
</LanguageSection>
## Problems
<problems-list problems={metadata.problems.general} />

View file

@ -22,30 +22,30 @@ export const metadata = {
usacoPast: [
new Problem("Gold", "Circular Barn Revisited", "622", "Normal", true, ["DP", "Brute Force"], "brute force starting location, then do dp[first i positions][number of doors used][position of last door] -> minimum distance cows need to travel"),
new Problem("Gold", "Taming the Herd", "815", "Normal", false, ["DP"], "dp[consider first i entries only][last breakout in first i occurs at j][k breakouts among first i entries] -> # changes"),
new Problem("Gold", "Moortal Cowmbat", "971", "Normal", true, ["DP", "Prefix Sums", "All Pairs Shortest Path"], "dp[first i letters form valid combo][last letter] -> time, Floyd Warshall on alphabet, then use prefix sums to speed up transitions."),
new Problem("Plat", "Team Building", "673", "Normal", false, [], ""),
new Problem("Gold", "Moortal Cowmbat", "971", "Hard", true, ["DP", "Prefix Sums", "All Pairs Shortest Path"], "dp[first i letters form valid combo][last letter] -> time, Floyd Warshall on alphabet, then use prefix sums to speed up transitions."),
new Problem("Plat", "Team Building", "673", "Hard", false, [], ""),
new Problem("Gold", "Stamp Painting", "791", "Hard", false, ["DP"], "must be K consectutive of same color, complimetary counting for dp[up to position i][number of consecutive] -> number of ways, find closed form to reduce runtime"),
],
knapsack: [
new Problem("CSES", "Unordered Coin Change", "1635", "Intro", true, ["DP", "Knapsack"], "dp[first i coins][sum] = number of ways, order of loops is capacity then coins, remember to take MOD after every computation"),
new Problem("CSES", "Ordered Coin Change", "1636", "Intro", true, ["DP", "Knapsack"], "dp[first i coins][sum] = number of ways, order of loops is coins then capacity, remember to take MOD after every computation"),
new Problem("CSES", "Minimum Coins", "1634", "Intro", true, ["DP", "Knapsack"], "dp[first i coins][sum] = minimum number of coins needed"),
new Problem("CSES", "Unordered Coin Change", "1635", "Easy", true, ["DP", "Knapsack"], "dp[first i coins][sum] = number of ways, order of loops is capacity then coins, remember to take MOD after every computation"),
new Problem("CSES", "Ordered Coin Change", "1636", "Easy", true, ["DP", "Knapsack"], "dp[first i coins][sum] = number of ways, order of loops is coins then capacity, remember to take MOD after every computation"),
new Problem("CSES", "Minimum Coins", "1634", "Easy", true, ["DP", "Knapsack"], "dp[first i coins][sum] = minimum number of coins needed"),
new Problem("AC", "Knapsack 2", "contests/dp/tasks/dp_e", "Easy", false, ["DP", "Knapsack"], "maximum capacity is large, and sum of values is small, so switch the states. dp[first i items][sum of values] = minimum capacity needed to achieve this sum"),
new Problem("Gold", "Fruit Feast", "574", "Easy", false, ["DP", "Knapsack"], "dp[fullness] = whether you can achieve this fullness"),
new Problem("Gold", "Talent Show", "839", "Hard", false, ["DP", "Knapsack", "Binary Search", "Math"], "binary search on optimal ratio, then do knapsack on weight"),
new Problem("CF", "Round Subset", "http://codeforces.com/contest/837/problem/D", "Normal", false, ["DP", "Knapsack"], "dp[i][j][l] -> maximum amount of twos we can collect by checking first i numbers, taking j of them with total power of five equal to l"),
],
pathsGrid: [
new Problem("LC", "Longest Common Subsequence", "https://leetcode.com/problems/longest-common-subsequence/", "Intro", true, ["DP"], "dp[first i characters in first string][first j characters in second string] -> longest common subsequence, transition if s[i] = t[j] for strings s and t"),
new Problem("HR", "Edit Distance", "contests/cse-830-homework-3/challenges/edit-distance", "Intro", true, ["DP"], "dp[first i characters in first string][first j characters in second string] -> edit distance"),
new Problem("AC", "Count Paths", "https://atcoder.jp/contests/dp/tasks/dp_h", "Intro", true, ["DP"], "dp[x][y] = number of paths up to the point (x,y) in grid"),
new Problem("LC", "Longest Common Subsequence", "https://leetcode.com/problems/longest-common-subsequence/", "Easy", true, ["DP"], "dp[first i characters in first string][first j characters in second string] -> longest common subsequence, transition if s[i] = t[j] for strings s and t"),
new Problem("HR", "Edit Distance", "contests/cse-830-homework-3/challenges/edit-distance", "Easy", true, ["DP"], "dp[first i characters in first string][first j characters in second string] -> edit distance"),
new Problem("AC", "Count Paths", "https://atcoder.jp/contests/dp/tasks/dp_h", "Easy", true, ["DP"], "dp[x][y] = number of paths up to the point (x,y) in grid"),
new Problem("Gold", "Cow Checklist", "670", "Easy", false, ["DP"], "dp[visited i Hs][visited j Gs][last cow visited on left/right] -> min energy"),
new Problem("Gold", "Radio Contact", "598", "Easy", false, ["DP"], "dp[up to ith step of Farmer John][up to jth step of bessie] = minimum distance"),
new Problem("Gold", "Why Did The Cow Cross the Road II", "598", "Normal", false, ["DP"], "dp[up to ith field on left side][up to jth field on right side] = maximum number of disjoint crosswalks"),
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/", "Intro", 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/", "Easy", true, ["DP"], "dp[i] = LIS up to i, use binary search to decrease runtime from quadratic"),
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"),
],
@ -56,6 +56,8 @@ Dynamic Programming is an important algorithmic technique in competitive program
(what's memoization? what's a good DP example?)
<IncompleteSection />
## Tutorial
The following tutorials serve as an introduction into the mindset of DP.

View file

@ -47,6 +47,10 @@ export const metadata = {
<spoiler title="Solution">
<LanguageSection>
<CPPSection>
```cpp
template<int SZ> struct SubtreeDP {
int par[SZ]; vi adj[SZ];
@ -105,6 +109,11 @@ int main() {
}
```
</CPPSection>
</LanguageSection>
</spoiler>
## Combining Subtrees

View file

@ -44,6 +44,9 @@ Note: You may prefer to use this in place of DFS for computing connected compone
</optional-content>
## Implementations
<IncompleteSection />
## Problems

View file

@ -4,7 +4,7 @@ title: "Introductory Number Theory"
author: Darren Yao, Michael Cao
prerequisites:
- Gold - Introduction to Dynamic Programming
description: Divisibility and Modular Arithmetic
description: Introduces divisibility and modular arithmetic.
frequency: 1
---
@ -98,13 +98,21 @@ $$
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:
$$ (a+b) \bmod m = (a \bmod m + b \bmod m) \bmod m $$
$$
(a+b) \bmod m = (a \bmod m + b \bmod m) \bmod m
$$
$$ (a-b) \bmod m = (a \bmod m - b \bmod m) \bmod m $$
$$
(a-b) \bmod m = (a \bmod m - b \bmod m) \bmod m
$$
$$ (a \cdot b) \pmod{m} = ((a \bmod m) \cdot (b \bmod m)) \bmod m $$
$$
(a \cdot b) \pmod{m} = ((a \bmod m) \cdot (b \bmod m)) \bmod m
$$
$$ a^b \bmod {m} = (a \bmod m)^b \bmod m $$
$$
a^b \bmod {m} = (a \bmod m)^b \bmod m
$$
### Modular Exponentiation
@ -131,7 +139,7 @@ long long binpow(long long x, long long n, long long m) {
Under a prime modulus, division can be performed using modular inverses.
To find the modular inverse of some number, simply raise it to the power of $\mathrm{MOD} - 2$, where $\mathrm{MOD}$ is the modulus being used, using the function described above. (The reasons for raising the number to $\mathrm{MOD} - 2$ can be explained with Euler's theorem, but we will not explain the theorem here).
To find the modular inverse of some number, simply raise it to the power of $\mathrm{MOD} - 2$, where $\mathrm{MOD}$ is the modulus being used, using the function described above. (The reasons for raising the number to $\mathrm{MOD} - 2$ can be explained with **Euler's theorem**, but we will not explain the theorem here).
The modular inverse is the equivalent of the reciprocal in real-number arithmetic; to divide $a$ by $b$, multiply $a$ by the modular inverse of $b$.
@ -139,6 +147,10 @@ Because it takes $\mathcal{O}(\log \mathrm{MOD})$ time to compute a modular inve
Also, one must always ensure that they do not attempt to divide by 0. Be aware that after applying modulo, a nonzero number can become zero, so be very careful when dividing by non-constant values.
(Ben - could have another module explaining modular inverses)
<IncompleteSection />
## Problems
<problems-list problems={metadata.problems.general} />

View file

@ -27,8 +27,6 @@ export const metadata = {
}
};
## Sample
<problems-list problems={metadata.problems.standard} />
## Resources
@ -41,6 +39,10 @@ export const metadata = {
<resource source="cp-algo" title="Kruskal's with DSU" url="graph/mst_kruskal_with_dsu.html"></resource>
</resources>
## Implementation
<IncompleteSection />
## USACO Problems
<problems-list problems={metadata.problems.general} />

View file

@ -67,6 +67,10 @@ A *Binary Indexed Tree* (aka *Fenwick Tree*) allows you to perform the following
<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)
<IncompleteSection />
## Finding $k$-th Element
Suppose that we want a data structure that supports all the operations as a `set` in C++ in addition to the following:
@ -86,7 +90,7 @@ Luckily, such a built-in data structure already exists in C++.
Using this, we can solve "Inversion Counting" in just a few lines (with template).
<spoiler title="INVCNT with Indexed Set">
<!-- <spoiler title="INVCNT with Indexed Set"> -->
```cpp
#include <bits/stdc++.h>
@ -113,7 +117,7 @@ int main() {
}
```
</spoiler>
<!-- </spoiler> -->
Note that if it were not the case that all elements of the input array were distinct, then this code would be incorrect since `Tree<int>` would remove duplicates. Instead, we would use an indexed set of pairs (`Tree<pair<int,int>>`), where the first element of each pair would denote the value while the second would denote the position of the value in the array.

View file

@ -57,12 +57,16 @@ Use *Dijkstra's Algorithm*.
The USACO training pages present a $O(N^2)$ version, although this is rarely used nowadays. (but describe anyways?)
<IncompleteSection />
#### Part 2: $O(M\log N)$
<resources>
<resource source="Benq" title="Dijkstra" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/graphs%20(12)/Basics/Dijkstra%20(7.3).h"> </resource>
</resources>
<IncompleteSection />
(comments in code?)
<optional-content title="Faster Dijkstra">

View file

@ -48,6 +48,10 @@ First we'll consider the special case when $\ominus$ denotes `min`.
</optional-content>
### Implementation
<IncompleteSection />
## Divide & Conquer
<problems-list problems={metadata.problems.diviSample} />
@ -75,6 +79,10 @@ A data structure known as **sqrt-tree** can speed up preprocessing time to $O(N\
</optional-content>
### Implementation
<IncompleteSection />
## Problems
<problems-list problems={metadata.problems.general} />

View file

@ -43,6 +43,10 @@ that if there exist pairs $(a,b)$ and $(c,d)$ in the map such that $a\le c$ and
If there are $N$ insertions, then each query takes $O(\log N)$ time and adding a pair takes $O(\log N)$ time amortized.
<LanguageSection>
<CPPSection>
```cpp
#define f first
#define s second
@ -50,17 +54,29 @@ If there are $N$ insertions, then each query takes $O(\log N)$ time and adding a
map<int,ll> m;
void ins(int a, ll b) {
auto it = m.lb(a); if (it != end(m) && it->s >= b) return;
it = m.insert(it,{a,b}); it->s = b;
while (it != begin(m) && prev(it)->s <= b) m.erase(prev(it));
auto it = m.lb(a); if (it != end(m) && it->s >= b) return;
it = m.insert(it,{a,b}); it->s = b;
while (it != begin(m) && prev(it)->s <= b) m.erase(prev(it));
}
ll query(int x) { auto it = m.lb(x);
return it == end(m) ? 0 : it->s; }
return it == end(m) ? 0 : it->s; }
// it = end(m) means that no pair satisfies a >= x
```
</CPPSection>
<JavaSection>
</JavaSection>
</LanguageSection>
## Problems
(easier examples?)
<IncompleteSection />
<problems-list problems={metadata.problems.problems} />

View file

@ -33,6 +33,10 @@ export const metadata = {
</resources>
### Implementation
<IncompleteSection />
My implementation can be found [here](https://github.com/bqi343/USACO/blob/master/Implementations/content/strings%20(14)/Light/HashRange%20(14.2).h). It uses two bases rather than just one to decrease the probability that two random strings hash to the same value. As mentioned in the articles above, there is no need to calculate modular inverses.
## Example: Cownomics (Gold)

View file

@ -52,12 +52,16 @@ A [topological sort](https://en.wikipedia.org/wiki/Topological_sorting) of a dir
(implementation)
<IncompleteSection />
### BFS
The BFS version, known as [Kahn's Algorithm](https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm), makes it obvious how to extract the lexicographically minimum topological sort.
(implementation)
<IncompleteSection />
## Dynamic Programming
<resources>
@ -81,6 +85,9 @@ $$
or zero if $v$ has in-degree $0$. If we process the states in topological order, it is guarangeed that $dp[u]$ will already have been computed before computing $dp[v]$.
(implementation?)
<IncompleteSection />
</spoiler>
<!-- However, not all problems clearly give you directed acyclic graphs (ex. [Plat - Cave Paintings](http://usaco.org/index.php?page=viewproblem2&cpid=996)). An important step in many problems is to reduce the statement into a directed acyclic graph. See the editorial of the linked problem for more information.

View file

@ -44,6 +44,10 @@ If we can preprocess a rooted tree such that every subtree corresponds to a cont
<resource source="CPH" title="18.2 - Subtrees & Paths" starred>introduces tree traversal array</resource>
</resources>
### Implementation
<IncompleteSection />
## LCA
<problems-list problems={metadata.problems.lca} />
@ -55,7 +59,9 @@ If we can preprocess a rooted tree such that every subtree corresponds to a cont
<resource source="cp-algo" title="Reducing LCA to RMQ" url="graph/lca.html" starred></resource>
</resources>
(implementation)
### Implementation
<IncompleteSection />
## Problems

View file

@ -5,7 +5,7 @@ import { useContext } from 'react';
export const IncompleteSection = props => {
return (
<div className="p-4 bg-red-100 text-red-800 rounded">
<b>This section is far from complete.</b> Feel free to file a request to
<b>This section is not complete.</b> Feel free to file a request to
complete this using the "Contact Us" button.
</div>
);