This commit is contained in:
Benjamin Qi 2020-07-19 21:34:33 -04:00
parent 91c1617467
commit 88d8ca807f
28 changed files with 241 additions and 165 deletions

View file

@ -19,6 +19,12 @@ You should read *all* the problems first (don't give up on any problems prematur
Problem difficulties can be out of order, so keep that in mind before focusing down 3 hours on problem 1 and not getting anywhere. Do a good amount of thinking on each problem before deciding which ones to focus on and which to put aside.
<Info title="Pro Tip">
Historically, the first platinum problem has never been the hardest (though you shouldn't count on this).
</Info>
### Time allocation
It's the worst feeling in the world to sink a couple hours into a problem before realizing that a different problem would've been easy pickings; we can easily avoid this situation with proper time allocation. You have to use your own judgement in deciding what is likely solvable and what should be quit. Generally, don't spend "too long" on one problem, and stay away from problems that look like they test something you don't know well.

View file

@ -5,16 +5,20 @@ author: Benjamin Qi
description: Contests that I participate in as well as a few tools.
---
See [clist.by](https://clist.by/coder/bqi343/) for an extensive list of contests. Make sure to [upsolve](https://en.wiktionary.org/wiki/upsolve) after the contest ends!
Make sure to [upsolve](https://en.wiktionary.org/wiki/upsolve) after the contest ends!
## Contests that I regularly participate in
<Resources>
<Resource source="CLIST" title="My Profile" url="https://clist.by/coder/bqi343/" starred>extensive list of contests</Resource>
<Resource source="kenkoooo" title="AtCoder Visualizer" url="https://kenkoooo.com/atcoder/#/table/Benq" starred>keep track of which problems you've done</Resource>
</Resources>
- [AtCoder](https://beta.atcoder.jp/contests/archive)
- probably the highest quality, although difficulty isn't *always* reasonable
- Contests
- Beginner / Regular: 4 or 6 problems, ~100 min
- Grand: 6 problems, 110 - 150 min
- [Visualizer](https://kenkoooo.com/atcoder/#/table/Benq)
- [Codeforces](http://codeforces.com/problemset)
- Contests
- Div 1/2/3/(4?): 5-6 problems (with some variations), 2 to 2.5 hrs
@ -29,26 +33,21 @@ See [clist.by](https://clist.by/coder/bqi343/) for an extensive list of contests
## Other Websites
- [Google Kickstart](https://codingcompetitions.withgoogle.com/kickstart)
- Feb - Nov
- [Kattis](https://open.kattis.com/)
- misc ICPC contests
- [HackerEarth](http://hackerearth.com/)
- Monthly "Easy"
- quality is not always good
- [Codechef](http://codechef.com/)
- Lunchtime, Cookoff
- quality is not always good
- [HackerRank](https://www.hackerrank.com/dashboard)
- Apparently there are only "Hack the Interview" contests now.
<Resources>
<Resource title="Kattis" url="https://open.kattis.com/">misc ICPC contests</Resource>
<Resource title="TOKI" url="https://tlx.toki.id/">Indonesian</Resource>
<Resource title="Kickstart" url="https://codingcompetitions.withgoogle.com/kickstart">Feb - Nov</Resource>
<Resource title="HackerEarth" url="http://hackerearth.com/">Monthly "Easy" - quality is not always good</Resource>
<Resource title="CodeChef" url="http://codechef.com/">Monthly Long, Lunchtime, Cookoff - quality is not always good</Resource>
<Resource title="HackerRank" url="https://www.hackerrank.com/dashboard">apparently only "Hack the Interview" contests now</Resource>
<Resource title="CSAcademy" url="https://csacademy.com/contest/archive/">no regular contests anymore, archive is still worth a look</Resource>
</Resources>
[CS Academy](https://csacademy.com/contest/archive/) does not hold regular contests anymore, but it's still worth looking at.
- Contests
<!-- - Contests
- Div 2: 5 problems, 2 hrs
- Open: 7 problems, 2 hrs
- Archive
- short statements, good editorials
- short statements, good editorials -->
## Onsite Finals (Individual)
@ -74,20 +73,25 @@ Only considering contests which allow C++ since the others aren't legit. (add mo
## Codeforces Tools
- [Stopstalk](https://www.stopstalk.com)
- [Code Drills](http://code-drills.com/)
- [CF Visualizer](http://cfviz.netlify.com/compare.html)
- [CF Rating Predictor](https://chrome.google.com/webstore/detail/cf-predictor/ocfloejijfhhkkdmheodbaanephbnfhn)
- [CF Command Line](https://codeforces.com/blog/entry/66552)
- [CF Editor](https://codeforces.com/blog/entry/72952)
<Resources>
<Resource title="CF-Predictor" url="https://chrome.google.com/webstore/detail/cf-predictor/ocfloejijfhhkkdmheodbaanephbnfhn" starred>estimate rating changes!</Resource>
<Resource title="Stopstalk" url="https://www.stopstalk.com">keep track of friends' progress</Resource>
<Resource title="Code Drills" url="https://recommender.codedrills.io/">problem recommender (haven't used personally) </Resource>
<Resource title="CF Visualizer" url="http://cfviz.netlify.com/compare.html">compare users </Resource>
<Resource title="CF Command Line Tool" url="https://codeforces.com/blog/entry/66552">parse problem statements, submit, etc from command line</Resource>
<Resource title="CF Editor" url="https://codeforces.com/blog/entry/72952">text editor using features from above</Resource>
</Resources>
<!-- - [CF Enhancer](https://chrome.google.com/webstore/detail/codeforces-enhancer/ocmandagmgmkcplckgnfgaokpgkfenmp)
- no longer works -->
## Contest Tools
- [2D Geo Visualizer](https://codeforces.com/blog/entry/70330)
- [CSAcademy Graph Editor (+ Geo Visualizer + Diff Tool)](https://csacademy.com/app/graph_editor/)
- [Desmos Grapher](https://www.desmos.com/calculator)
- [Wolfram Alpha](https://www.wolframalpha.com/)
- [OEIS](https://oeis.org/)
<Resources>
<Resource title="Wolfram Alpha" url="https://www.wolframalpha.com/" starred> </Resource>
<Resource title="CSAcademy Graph Editor, Geo Visualizer" url="https://csacademy.com/app/graph_editor/" starred> </Resource>
<Resource title="Desmos Grapher" url="https://www.desmos.com/calculator" starred> </Resource>
<Resource title="Diff Checker" url="https://www.diffchecker.com/"> </Resource>
<Resource title="2D Geo Visualizer (C++)" url="https://codeforces.com/blog/entry/70330"></Resource>
<Resource title="OEIS" url="https://oeis.org/">integer sequences</Resource>
</Resources>

View file

@ -3,6 +3,8 @@ id: factors-choosing
title: "Factors to Consider When Choosing a Language"
author: Benjamin Qi
description: Reasons why choice of language matters significantly outside of USACO Bronze.
prerequisites:
- choosing-lang
---
## Notes

View file

@ -13,6 +13,7 @@ export const problems = {
new Problem("HR", "Bubble Sort", "https://www.hackerrank.com/challenges/ctci-bubble-sort/problem", "Very Easy", false, [], ""),
],
easy: [
new Problem("CF", "Kayaking", "contest/863/problem/B", "Easy", false, [], ""),
new Problem("CSES", "Distinct Numbers", "1621", "Easy"),
new Problem("CSES", "Stick Lengths", "1074", "Normal", false, [], "Spoiler: Optimal length is median"),
],

View file

@ -17,11 +17,10 @@ export const problems = {
ad: [
new Problem("CSES", "Sum of Three Values", "1641", "Easy", false, [], ""),
new Problem("Silver", "Diamond Collector", "643", "Easy", false, ["2P", "Sorting"], ""),
new Problem("CF", "Books", "problemset/problem/279/B", "Easy", false, ["2P"]),
new Problem("CF", "Cellular Network", "problemset/problem/702/C", "Easy", false, []),
new Problem("CF", "USB vs. PS/2", "problemset/problem/762/B", "Easy", false, []),
new Problem("Silver", "Sleepy Cow Herding", "918", "Normal", false, ["2P", "Sorting"], ""),
new Problem("CF", "Books", "problemset/problem/279/B", "Normal", false, []),
new Problem("CF", "Cellular Network", "problemset/problem/702/C", "Normal", false, []),
new Problem("CF", "USB vs. PS/2", "problemset/problem/762/B", "Normal", false, []),
new Problem("CF", "K-Good Segment", "problemset/problem/616/D", "Normal", false, []),
new Problem("CF", "Garland", "problemset/problem/814/C", "Normal", false, []),
new Problem("CF", "Jury Meeting", "problemset/problem/853/B", "Normal", false, []),
],
@ -29,6 +28,8 @@ export const problems = {
<Problems problems={problems.sample} />
## Resources
<Resources>
<Resource source="CPH" title="8.1 - Two Pointers" starred>solutions to the problems above</Resource>
<Resource source="IUSACO" title="14.1 - Two Pointers"></Resource>

View file

@ -6,7 +6,7 @@ prerequisites:
- sorting-custom
- intro-ordered
- lambda
description: "More ways to write custom comparators in C++ and incorporating them into STL objects."
description: "Incorporating custom comparators into STL objects."
frequency: 1
---
@ -17,7 +17,7 @@ frequency: 1
<br />
What if we want to use a C++ `set` with the `Edge` struct that was defined in "Sorting with Custom Comparators"?
What if we want to use a C++ `set` with the `Edge` struct that was defined in [Sorting with Custom Comparators](./sorting-custom)?
## Operator Overloading

View file

@ -26,10 +26,12 @@ export const problems = {
new Problem("Silver", "Why Did the Cow Cross the Road III", "716", "Normal", false, []),
new Problem("Silver", "Multiplayer Moo", "836", "Hard", false, []),
new Problem("Silver", "Snow Boots", "811", "Hard", false, []),
new Problem("Silver", "Mooyo Mooyo", "860", "Hard", false, []),
new Problem("Silver", "Mooyo Mooyo", "860", "Normal", false, [], ""),
],
};
<!-- Mooyo Mooyo: Not a sorting problem, but you can use sorting to simulate gravity. - Write a custom comparator which puts zeroes at the front and use `stable_sort` to keep the relative order of other elements the same. -->
<Problems problems={problems.sample} />
<br />

View file

@ -16,14 +16,14 @@ export const problems = {
new Problem("CF", "Div 2 B - Badge", "contest/1020/problem/B", "Very Easy", false, ["Func Graph"], "Try to solve the problem in $O(N)$!"),
],
general: [
new Problem("Silver", "The Bovine Shuffle", "764", "Normal", false, ["Func Graph"], "Try to solve the problem in $O(N)$!"),
new Problem("Silver", "The Bovine Shuffle", "764", "Easy", false, ["Func Graph"], "Try to solve the problem in $O(N)$!"),
new Problem("CSES", "Planets Cycles", "1751", "Normal", false, ["Func Graph"], ""),
new Problem("Silver", "Swapity Swapity Swap", "1014", "Normal", false, ["Permutation"], ""),
new Problem("Codeforces", "Cooperative Game", "https://codeforces.com/contest/1137/problem/D", "Normal", false, ["Func Graph, Floyd's Algorithm"], "Implement Floyd's Algorithm! (You only actually need 3 friends to solve the problem!)"),
new Problem("CF", "Cooperative Game", "https://codeforces.com/contest/1137/problem/D", "Normal", false, ["Func Graph, Floyd's Algorithm"], "Implement Floyd's Algorithm! (You only actually need 3 friends to solve the problem!)"),
new Problem("POI", "Mafia", "https://szkopul.edu.pl/problemset/problem/w3YAoAT3ej27YeiaNWjK57_G/site/?key=statement", "Hard", false, ["Func Graph"], ""),
new Problem("POI", "Spies", "https://szkopul.edu.pl/problemset/problem/r6tMTfvQFPAEfQioYMCQndQe/site/?key=statement", "Hard", false, [], ""),
new Problem("POI", "Frog", "https://szkopul.edu.pl/problemset/problem/qDH9CkBHZKHY4vbKRBlXPrA7/site/?key=statement", "Hard", false, [], ""),
new Problem("ojuz", "Space Pirate", "JOI14_space_pirate", "Very Hard", false, ["Graphs"], "One of the most difficult problems of all time. Build a tree with a single back edge. Break into three cases: path -> other cycle, path -> subtree, path -> non-subtree. Then perform some black magic."),
new Problem("ojuz", "Space Pirate", "JOI14_space_pirate", "Insane", false, ["Graphs"], "One of the most difficult problems of all time. Build a tree with a single back edge. Break into three cases: path -> other cycle, path -> subtree, path -> non-subtree. Then perform some black magic."),
],
};
@ -41,7 +41,7 @@ This is also commonly referred to as a **successor graph**.
### Resources
<Resources>
<Resource source="CPH" title="16.3, 16.4 - Successor Graphs"></Resource>
<Resource source="CPH" title="16.3 Successor Graphs"></Resource>
</Resources>
### Implementation
@ -82,13 +82,12 @@ int main()
</LanguageSection>
## Tortoise and Hare (Floyd's Algorithm)
## Floyd's Algorithm
**Floyd's Algorithm**, also commonly referred to as the **Tortoise and Hare Algorithm**, is capable of detecting cycles in a functional graph in $O(N)$ time and $O(1)$ memory (not counting the graph itself)
### Resources
<Resources>
<Resource source="CPH" title="16.4 - Cycle Detection" starred></Resource>
<Resource source="Medium" title="The Tortoise and the Hare (Floyd's Algorithm)" url="https://medium.com/@tuvo1106/the-tortoise-and-the-hare-floyds-algorithm-87badf5f7d41"></Resource>
</Resources>

View file

@ -25,24 +25,22 @@ export const problems = {
new Problem("CSES", "Movie Festival II", "1632", "Easy", false, [], ""),
new Problem("CSES", "Stick Division", "1161", "Hard", false, [], ""),
],
usaco: [
new Problem("Silver", "Paired Up", "738", "Easy", false, ["2P", "Sorting"]),
new Problem("Silver", "Lemonade Line", "835", "?", false, [], ""),
new Problem("Silver", "Why ... (helpcross)", "714", "?", false, [], "first step: sort!"),
new Problem("Silver", "Berry Picking", "990", "?", false, [], ""),
new Problem("Silver", "Rest Stops", "810", "?", false, [], ""),
new Problem("Silver", "High Card Wins", "571", "?", false, [], ""),
],
other: [
new Problem("CSA", "Sure Bet", "sure-bet", "?", false, [], ""),
new Problem("CF", "Did you Mean...", "contest/860/problem/A", "?", false, [], ""),
new Problem("CF", "Bus", "contest/864/problem/C", "?", false, [], ""),
new Problem("CF", "Permutation", "contest/864/problem/D", "?", false, [], ""),
new Problem("CF", "Kayaking", "contest/863/problem/B", "?", false, [], "Huffman Coding?"),
new Problem("CF", "New Year and Three Musketeers", "contest/611/problem/E", "Hard", false, [], "needs maps"),
]
new Problem("Silver", "Paired Up", "738", "Easy", false, ["2P", "Sorting"]),
new Problem("Silver", "Lemonade Line", "835", "Easy", false, ["Sorting"], ""),
new Problem("Silver", "High Card Wins", "571", "Easy", false, [], ""),
new Problem("Silver", "Berry Picking", "990", "Normal", false, [], ""),
new Problem("Silver", "Why ... (helpcross)", "714", "Normal", false, ["Sorting"], ""),
new Problem("CSA", "Sure Bet", "sure-bet", "Normal", false, [], ""),
],
};
<!-- new Problem("Silver", "Rest Stops", "810", "?", false, [], ""), -->
<!-- new Problem("CF", "Did you Mean...", "contest/860/problem/A", "?", false, [], ""), -->
<!-- new Problem("CF", "Bus", "contest/864/problem/C", "?", false, [], ""), -->
<!-- new Problem("CF", "Permutation", "contest/864/problem/D", "?", false, [], ""), -->
<!-- new Problem("CF", "New Year and Three Musketeers", "contest/611/problem/E", "Hard", false, [], "needs maps"), -->
<Resources>
<Resource source="IUSACO" title="9 - Greedy Algorithms">Module is based off this.</Resource>
<Resource source="CPH" title="6 - Greedy Algorithms" starred></Resource>
@ -177,10 +175,6 @@ pw.close();
<Problems problems={problems.cses} />
## USACO Problems
<Problems problems={problems.usaco} />
## Other Problems
<Problems problems={problems.other} />

View file

@ -28,6 +28,12 @@ export const problems = {
]
};
<Warning>
This is **not** built into Python. The Python [OrderedDict](https://docs.python.org/3/library/collections.html#collections.OrderedDict) stores keys in the same order as they were inserted in, **not** in sorted order.
</Warning>
<Resources>
<Resource source="IUSACO" title="4.3 - Sets & Maps">module is based off this</Resource>
<Resource source="CPH" title="4.2 to 4.4 - Data Structures" starred>sets, maps, set iterators</Resource>
@ -37,15 +43,16 @@ export const problems = {
In **ordered** sets and maps, the entries are sorted in order of key. Insertions, deletions, and searches are all $O(\log N)$, where $N$ is the number of elements in the set or map. Accessing or removing the next key higher or lower than some input $k$ is also supported.
(**not** the same as [OrderedDict](https://docs.python.org/3/library/collections.html#collections.OrderedDict) in Python ...)
## Ordered Sets
<LanguageSection>
<CPPSection>
As well as those supported by `unordered_set`, the ordered set also allows four additional operations: `begin()`, which returns an iterator to the lowest element in the set, `end()`, which returns an iterator to the highest element in the set, `lower_bound`, which returns an iterator to the least element greater than or equal to some element `k`, and `upper_bound`, which returns an iterator to the least element strictly greater than some element `k`.
In addition to the `unordered_set` operations mentioned in the prerequisite module, the ordered `set` also allows:
- `lower_bound`: returns an iterator to the least element greater than or equal to some element `k`
- `upper_bound`: returns an iterator to the least element strictly greater than some element `k`.
```cpp
set<int> s;
@ -88,7 +95,7 @@ System.out.println(set.higher(23); // ERROR, no such element exists
</LanguageSection>
One limitation of the ordered set is that we can't efficiently access the $k^{th}$ largest element in the set, or find the number of elements in the set greater than some arbitrary $x$. These operations can be handled using a data structure called an **order statistic tree** (see Gold - Point Update Range Sum).
One limitation of the ordered set is that we can't efficiently access the $k^{th}$ largest element in the set, or find the number of elements in the set greater than some arbitrary $x$. These operations can be handled using a data structure called an [order statistic tree](../gold/PURS#order-statistic-tree).
## Ordered Maps
@ -96,7 +103,10 @@ One limitation of the ordered set is that we can't efficiently access the $k^{th
<CPPSection>
The ordered map supports all of the operations that an `unordered_map` supports, and additionally supports `lower_bound` and `upper_bound`, returning the iterator pointing to the lowest entry not less than the specified key, and the iterator pointing to the lowest entry strictly greater than the specified key respectively.
In addition to the `unordered_map` operations mentioned in the prerequisite module, the ordered `map` also allows:
- `lower_bound`: returns the iterator pointing to the lowest entry not less than the specified key
- `upper_bound`: returns the iterator pointing to the lowest entry strictly greater than the specified key respectively.
```cpp
map<int, int> m;
@ -144,7 +154,10 @@ A **multiset** is a sorted set that allows multiple copies of the same element.
<CPPSection>
In addition to all of the regular set operations, the multiset `count()` method returns the number of times an element is present in the multiset. However, this method takes time **linear** in the number of matches so you shouldn't use it in a contest. The `begin()`, `end()`, `lower_bound()`, and `upper_bound()` operations work the same way they do in the normal sorted set. **Warning:** If you want to remove a value *once*, make sure to use `multiset.erase(multiset.find(val))` rather than `multiset.erase(val)`. The latter will remove *all* instances of `val`.
In addition to all of the regular set operations,
- the `count()` method returns the number of times an element is present in the multiset. However, this method takes time **linear** in the number of matches so you shouldn't use it in a contest.
- If you want to remove a value *once*, make sure to use `multiset.erase(multiset.find(val))` rather than `multiset.erase(val)`. The latter will remove *all* instances of `val`.
```cpp
@ -198,11 +211,26 @@ static void remove(int x){
</LanguageSection>
## Using Iterators
<LanguageSection>
<CPPSection>
next(), prev(), ++, --
</CPPSection>
</LanguageSection>
<IncompleteSection />
## Priority Queues
A **priority queue** supports the following operations: insertion of elements, deletion of the element considered highest priority, and retrieval of the highest priority element, all in $O(\log N)$ time according to the number of elements in the priority queue. Like sets, priority is based on a **comparator function**.
Of course, all of these functions are supported by multisets, but priority queues are simpler (so they are much faster).
Of course, all of these functions are supported by multisets, but priority queues are simpler and faster.
<LanguageSection>
@ -246,32 +274,22 @@ pq.add(6); // [7, 6, 5]
</LanguageSection>
## Using Iterators
## Introductory Problems
<Problems problems={problems.standard} />
## Harder Example: Bit Inversions
<Problems problems={problems.sample} />
### Solution
<Spoiler title="Solution">
<LanguageSection>
<CPPSection>
next(), prev(), ++, --
</CPPSection>
</LanguageSection>
<IncompleteSection />
## Easy
<Problems problems={problems.standard} />
## Example: Using Iterators
<Problems problems={problems.sample} />
<Spoiler title="Solution">
```cpp
#include <bits/stdc++.h>
using namespace std;
@ -322,7 +340,7 @@ Note that `multiset` has a high constant factor, so replacing `ret` with an arra
#include <bits/stdc++.h>
using namespace std;
#define sz(x) (x).size()
#define sz(x) (int)(x).size()
string s;
int m;
@ -361,10 +379,13 @@ int main() {
}
```
</CPPSection>
</LanguageSection>
</Spoiler>
<IncompleteSection />
## Problems
## Harder Problems
<Problems problems={problems.general} />

View file

@ -20,7 +20,6 @@ export const problems = {
new Problem("Silver", "Lifeguards", "786", "Easy", false, [], "Similar to above."),
new Problem("Silver", "Rental Service", "787", "Easy", false, [], ""),
new Problem("Silver", "Mountains", "896", "Easy", false, [], ""),
new Problem("Silver", "Mooyo Mooyo", "860", "Easy", false, [], "Not a sorting problem, but you can use sorting to simulate gravity. - Write a custom comparator which puts zeroes at the front and use `stable_sort` to keep the relative order of other elements the same."),
new Problem("Gold", "Splitting the Field", "645", "Normal", false, [], ""),
new Problem("Silver", "Triangles", "1015", "Hard", false, [], ""),
new Problem("Silver", "Meetings", "967", "Very Hard", false, [], ""),
@ -28,7 +27,8 @@ export const problems = {
};
<Resources>
<Resource source="IUSACO" title="8 - Sorting & Comparators"></Resource>
<Resource source="IUSACO" title="8 - Sorting & Comparators">partially based off this</Resource>
<Resource source="CPH" title="3.2 - User-Defined Structs, Comparison Functions">short overflow of what this module will cover</Resource>
</Resources>
<br />
@ -55,7 +55,7 @@ After sorting, it should look like
2 3 10
```
With C++, the easiest method is to use nested pairs or a `vector` of `array<int,3>` or `vector<int>`.
With C++, the easiest method is to use a `vector` of nested `pair`s:
```cpp
#include <bits/stdc++.h>
@ -76,6 +76,8 @@ int main() {
}
```
or a `vector` of `array<int,3>`s or `vector<int>`s:
```cpp
int main() {
int M = 4;
@ -91,10 +93,10 @@ int main() {
In Python, we can use a list of lists.
But in Java, we can't immediately sort an arraylist of arraylists. What should we do?
But in Java, we can't sort an `ArrayList` of `ArrayList`s without writing some additional code. What should we do?
- If we only stored the edge weights and sorted them, we would have a sorted list of edge weights, but it would be impossible to tell which weights corresponded to which edges.
- However, if we create a **class** (or struct) representing the edges and define a **custom comparator** to sort them by weight, we can sort the edges in ascending order while also keeping track of their endpoints.
- However, if we create a **class** representing the edges and define a **custom comparator** to sort them by weight, we can sort the edges in ascending order while also keeping track of their endpoints.
## Classes
@ -105,6 +107,10 @@ First, we need to define a **class** that represents what we want to sort. In ou
<CPPSection>
### C++
A C++ `struct` is the same as a class in C++, but all members are public by default.
```cpp
#include <bits/stdc++.h>
using namespace std;
@ -113,6 +119,13 @@ struct Edge {
int a,b,w;
};
/* alternatively,
class Edge {
public:
int a,b,w;
};
*/
int main() {
int M = 4;
vector<Edge> v;
@ -188,10 +201,6 @@ Normally, sorting functions rely on moving objects with a lower value in front o
<CPPSection>
<Resources>
<Resource source="CPH" title="3.2 - User-Defined Structs, Comparison Functions" starred></Resource>
</Resources>
What a comparator does is compare two objects as follows, based on our comparison criteria:
- If object $x$ is less than object $y$, return `true`
@ -201,7 +210,7 @@ Essentially, the comparator determines whether object $x$ belongs to the left of
In addition to returning the correct answer, comparators should also satisfy the following conditions:
- The function must be consistent with respect to reversing the order of the arguments: if $x \neq y$ and `compare(x, y)`is `true`, then `compare(y, x)` should be `false` and vice versa.
- The function must be consistent with respect to reversing the order of the arguments: if $x \neq y$ and `compare(x, y)` is `true`, then `compare(y, x)` should be `false` and vice versa.
- The function must be transitive. If `compare(x, y)` is true and `compare(y, z)` is true, then `compare(x, z)` should also be true. If the first two compare functions both return `false`, the third must also return `false`.
### Method 1: Overloading the Less Than Operator
@ -209,7 +218,7 @@ In addition to returning the correct answer, comparators should also satisfy the
This is the easiest to implement. However, it only works for objects (not primitives) and it doesn't allow you to define multiple ways to compare the same type of class.
In the context of Wormhole Sort (note the use of
[const T&](https://stackoverflow.com/questions/11805322/why-should-i-use-const-t-instead-of-const-t-or-t)):
[const Edge&](https://stackoverflow.com/questions/11805322/why-should-i-use-const-t-instead-of-const-t-or-t)):
```cpp
#include <bits/stdc++.h>
@ -278,7 +287,7 @@ int main() {
```
We can also use lambda expressions in C++11 or above:
We can also use [lambda expressions](../intro/lambda) in C++11 or above:
```cpp
sort(begin(v),end(v),[](const Edge& x, const Edge& y) { return x.w < y.w; });

View file

@ -1,6 +1,6 @@
---
id: intro-dp
title: "Introduction to Dynamic Programming"
title: "Introduction to Dynamic Programming (DP)"
author: Michael Cao
prerequisites:
- complete-search
@ -51,11 +51,17 @@ export const problems = {
],
}
Dynamic Programming is an important algorithmic technique in competitive programming that appears at all levels of competition.
**Dynamic Programming** (DP) is an important algorithmic technique in competitive programming that appears at all levels of competition.
By breaking down the full task into sub-problems, Dynamic Programming avoids the redundant computations of brute force solutions.
<IncompleteSection>
Although it is not too difficult to grasp the general ideas behind Dynamic Programming, or DP, the technique can be used in a diverse range of problems and is a must-know idea for competitors in the USACO gold division.
What do you mean by "all levels"? Certainly doesn't appear in silver ...
</IncompleteSection>
By breaking down the full task into sub-problems, DP avoids the redundant computations of brute force solutions.
Although it is not too difficult to grasp the general ideas behind DP, the technique can be used in a diverse range of problems and is a must-know idea for competitors in the USACO gold division.
## Introductory Resources

View file

@ -133,49 +133,51 @@ Don't just dive into trying to figure out a DP state and transitions -- make som
<Spoiler title="Ostap & Tree">
Solution described by editorial is terrible, but we can do better! This runs in $O(NK)$ time. (proof?)
```cpp
vmi yes[101], no[101];
int n,k;
vi adj[MX];
void dfs(int x, int y) {
yes[x] = no[x] = {1}; // black, not black
// dist of closest good vertex
// or dist of farthest bad vertex
auto ad = [](vmi& a, int b, mi c) {
while (sz(a) <= b) a.pb(0);
a[b] += c;
};
trav(t,adj[x]) if (t != y) {
dfs(t,x);
yes[t].insert(begin(yes[t]),0);
no[t].insert(begin(no[t]),0);
if (sz(no[t]) > k+1) no[t].pop_back();
vmi YES, NO;
F0R(i,sz(yes[x])) F0R(j,sz(yes[t])) ad(YES,min(i,j),yes[x][i]*yes[t][j]);
F0R(i,sz(no[x])) F0R(j,sz(no[t])) ad(NO,max(i,j),no[x][i]*no[t][j]);
auto yesNo = [&](vmi good, vmi bad) {
F0R(i,sz(good)) F0R(j,sz(bad)) {
if (i+j <= k) ad(YES,i,good[i]*bad[j]);
else ad(NO,j,good[i]*bad[j]);
}
};
yesNo(yes[x],no[t]); yesNo(yes[t],no[x]);
swap(yes[x],YES); swap(no[x],NO);
}
yes[x] = no[x] = {1}; // black, not black
// dist of closest good vertex
// or dist of farthest bad vertex
auto ad = [](vmi& a, int b, mi c) {
while (sz(a) <= b) a.pb(0);
a[b] += c;
};
trav(t,adj[x]) if (t != y) {
dfs(t,x);
yes[t].insert(begin(yes[t]),0);
no[t].insert(begin(no[t]),0);
if (sz(no[t]) > k+1) no[t].pop_back();
vmi YES, NO;
F0R(i,sz(yes[x])) F0R(j,sz(yes[t])) ad(YES,min(i,j),yes[x][i]*yes[t][j]);
F0R(i,sz(no[x])) F0R(j,sz(no[t])) ad(NO,max(i,j),no[x][i]*no[t][j]);
auto yesNo = [&](vmi good, vmi bad) {
F0R(i,sz(good)) F0R(j,sz(bad)) {
if (i+j <= k) ad(YES,i,good[i]*bad[j]);
else ad(NO,j,good[i]*bad[j]);
}
};
yesNo(yes[x],no[t]); yesNo(yes[t],no[x]);
swap(yes[x],YES); swap(no[x],NO);
}
}
int main() {
setIO(); re(n,k);
F0R(i,n-1) {
int a,b; re(a,b);
adj[a].pb(b), adj[b].pb(a);
}
dfs(1,0);
mi ans = 0;
trav(t,yes[1]) ans += t;
ps(ans);
// you should actually read the stuff at the bottom
setIO(); re(n,k);
F0R(i,n-1) {
int a,b; re(a,b);
adj[a].pb(b), adj[b].pb(a);
}
dfs(1,0);
mi ans = 0;
trav(t,yes[1]) ans += t;
ps(ans);
// you should actually read the stuff at the bottom
}
```

View file

@ -31,10 +31,12 @@ export const problems = {
<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>
<Resource source="PAPS" title="16.1, 16.2, 16.4 - Number Theory"></Resource>
</Resources>
<!-- <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>
-->
## Prime Factorization
<Problems problems={problems.sample} />
@ -204,7 +206,13 @@ We'll only consider **prime** moduli here. Division can be performed using modul
#### With Exponentiation
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 **Fermat's Little 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 **Fermat's Little Theorem**.
<IncompleteSection>
explain theorem?
</IncompleteSection>
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$.
@ -212,12 +220,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.
<IncompleteSection />
#### With Extended Euclidean Algorithm
<Optional>
See the module in the [Advanced](../adv/extend-euclid) section.
</Optional>

View file

@ -3,8 +3,8 @@ id: mst
title: "Minimum Spanning Trees"
author: Benjamin Qi
prerequisites:
- Gold - Shortest Paths with Non-Negative Edge Weights
- Gold - Disjoint Set Union
- sp
- dsu
description: "A subset of the edges of a connected, undirected, edge-weighted graph that connects all the vertices to each other of minimum total weight, where no cycles are allowed."
frequency: 2
---

View file

@ -4,7 +4,7 @@ title: "Point Update Range Sum"
author: Benjamin Qi
prerequisites:
- prefix-sums
description: "Introducing Segment Trees, Binary Indexed Trees, and Indexed Sets (C++ only)."
description: "Introduces Segment Tree, Binary Indexed Tree, and Order Statistic Tree (C++ only)."
frequency: 3
---
@ -147,7 +147,7 @@ Suppose that we want a data structure that supports all the operations as a `set
- `order_of_key(x)`: counts the number of elements in the set that are strictly less than `x`.
- `find_by_order(k)`: similar to `find`, returns the iterator corresponding to the `k`-th lowest element in the set (0-indexed).
### Indexed Set
### Order Statistic Tree
Luckily, such a built-in data structure already exists in C++.

View file

@ -20,6 +20,11 @@ export const problems = {
],
};
<Resources>
<Resource source="CPH" title="4.5 - Queues, Deques"></Resource>
<Resource source="PAPS" title="3.2, 6.3 - Queues"></Resource>
</Resources>
## Queues
A queue is a First In First Out (FIFO) data structure that supports three operations, all in $O(1)$ time.
@ -90,6 +95,8 @@ d.push_front(1); // [1, 3, 7]
d.pop_back(); // [1, 3]
```
(important: you can also access like array ...)
</CPPSection>
<JavaSection>

View file

@ -112,4 +112,6 @@ just to be safe.
<Problems problems={problems.apsp} />
(more?)
(more?)
<IncompleteSection />

View file

@ -22,9 +22,11 @@ export const problems = {
],
};
Given a static array $A[1],A[2],\ldots,A[N]$, you want to answer queries in the form $A[l]\ominus A[l+1]\ominus \cdots \ominus A[r]$ where $\ominus$ denotes any associative operation.
With $O(N\log N)$ time preprocessing, we can get $O(1)$ queries.
Given a static array $A[1],A[2],\ldots,A[N]$, you want to answer queries in the form
$$
A[l]\ominus A[l+1]\ominus \cdots \ominus A[r]
$$
where $\ominus$ denotes any associative operation. With $O(N\log N)$ time preprocessing, we can get $O(1)$ time queries!
## [Range Minimum Query](https://en.wikipedia.org/wiki/Range_minimum_query)

View file

@ -20,8 +20,11 @@ export const problems = {
new Problem("CSES", "Sliding Median", "1076", "Normal", false, [], ""),
new Problem("CSES", "Sliding Cost", "1077", "Hard", false, [], ""),
],
general: [
sam: [
new Problem("CSES", "Playlist", "1141", "Easy", false, ["2P"], ""),
],
general: [
new Problem("CF", "K-Good Segment", "problemset/problem/616/D", "Easy", false, []),
new Problem("Gold", "Haybale Feast", "767", "Easy", false, ["Set", "Sliding Window"]),
new Problem("Plat", "Fort Moo", "600", "Hard", false, ["Sliding Window"]),
]
@ -42,7 +45,6 @@ For each position of the window, we want to compute some information. For exampl
-->
<Resources>
<Resource source="Medium" title="Introduction to Sliding Window Algorithms" url="https://levelup.gitconnected.com/an-introduction-to-sliding-window-algorithms-5533c4fe1cc7"> </Resource>
<Resource source="GFG" title="Window Sliding Technique" url="window-sliding-technique"> </Resource>
</Resources>
@ -58,4 +60,14 @@ For each position of the window, we want to compute some information. For exampl
In general, it is not required for the subarray to have constant size as long as both the left and right endpoints of the subarray only move to the right.
<Problems problems={problems.sam} />
### Solution
<Resources>
<Resource source="Medium" title="Introduction to Sliding Window Algorithms" url="https://levelup.gitconnected.com/an-introduction-to-sliding-window-algorithms-5533c4fe1cc7"> </Resource>
</Resources>
### Problems
<Problems problems={problems.general} />

View file

@ -3,7 +3,7 @@ id: springboards
title: "Max Suffix Query with Insertions Only"
author: Benjamin Qi
prerequisites:
- harder-ordered
- intro-ordered
description: "A solution to USACO Gold - Springboards."
frequency: 1
---

View file

@ -22,9 +22,8 @@ export const problems = {
};
<Resources>
<Resource source="CPH" title="4.5 - Stacks, Queues, Priority Queues"></Resource>
<Resource source="PAPS" title="3.2 to 3.4 - C++ STL"></Resource>
<Resource source="PAPS" title="6.2, 6.3, 6.5 - Stacks, Queues, Priority Queues"></Resource>
<Resource source="CPH" title="4.5 - Stacks"></Resource>
<Resource source="PAPS" title="3.3, 6.2 - Stacks"></Resource>
<Resource source="CP1" title="2.2 - Data Structures with Built-in Libraries"> </Resource>
</Resources>

View file

@ -3,8 +3,8 @@ id: toposort
title: "Topological Sort"
author: Benjamin Qi, Michael Cao, Nathan Chen
prerequisites:
- Gold - Breadth First Search
- Gold - Introduction to Dynamic Programming
- bfs
- intro-dp
description: "An ordering of vertices in a directed acyclic graph that ensures that a node is visited before a node it has a directed edge to."
frequency: 1
---

View file

@ -53,6 +53,7 @@ const sources = {
};
export const sourceTooltip = {
AoPS: 'Art of Problem Solving',
CPH: "Book - Competitive Programmer's Handbook",
PAPS: 'Book - Principles of Algorithmic Problem Solving',
IUSACO: 'Book - An Introduction to the USA Computing Olympiad',