Update to latest version #4

Merged
Ta180m merged 123 commits from master into master 2020-06-18 19:15:27 +00:00
92 changed files with 4398 additions and 2154 deletions

152
Content Documentation.md Normal file
View file

@ -0,0 +1,152 @@
## Content Formatting Documentation
All modules are written in [Markdown](https://www.markdownguide.org/cheat-sheet/). There are special additions to the markdown that we have added to this site.
These special additions are still under development, so they may change frequently.
If you are confused about something, or if there's a certain feature that you want to add, reach out to Nathan Wang.
You can use [StackEdit](https://stackedit.io/) to check that latex renders properly.
### `ordering.js`
Located at `content/ordering.js`, this file stores the ordering of the modules. Hopefully the format is self-explanatory
(it matches based on "slug"). Let Nathan Wang know if you have questions.
### Frontmatter
[Frontmatter](https://jekyllrb.com/docs/front-matter/) is the stuff in the beginning of each module that's surrounded
by three dashes. Frontmatter is written in [YAML](https://yaml.org/). It stores the "metadata" for each module.
YAML formatting is _extremely strict_. Be careful about spaces.
- **ID**: _Required_. The ID of the module. Ex: `getting-started`, or `containers`. This ID is used to identify
the module, so make sure it is **unique** and **all lowercase with dashes only**. The URL will be generated based off this.
- **Title**: _Required_. The title of the module. Ex: `Getting Started`
- **Author**: _Required_. The author of the module. Ex: `Unknown`
- **Prerequisites**: _Optional_. Any prerequisites for this module.
The prerequisite formatting is rather unintuitive. It expects an array of arrays, where the first item is
the name of the prerequisite, and the optional second item is a link. **Note the number of spaces!**
Example:
```
prerequisites:
-
- Prerequisite Name
- https://dummy.prerequisite.link.com/
-
- Another Prerequisite Without a Link
```
- **Problems**: _Optional_. A list of problems in the article. As we haven't figured out what we're going to do with
**it's best to not include this yet.** For USACO problems, enter each problem as `division_filename`. Ex: `bronze_promote`.
### Module Description
Everything contained in `module-excerpt` tags is part of the "module description." It gets rendered on the homepage. Be careful not to use headers
as they will look really weird on the homepage. The module description is also included in the article itself.
If you don't want a description for the module, just put the `END DESCRIPTION` line as the first line
after the frontmatter.
If you want a description that appears only on the homepage but not the article, wrap it in
an HTML element with the class `syllabus-only`. Note that you can't use markdown in HTML elements.
Example:
```
<module-excerpt>
<ul class="syllabus-only">
<li>Contest Format</li>
<li>Choosing a Language</li>
<li>Practicing and Debugging</li>
<li>Contest Strategies</li>
</ul>
</module-excerpt>
```
This will render as a list in the homepage, but won't appear in the article.
### Spoilers
Spoilers are collapsible elements that only show themselves when the user clicks on it. It's useful
when writing solutions to problems. The styling of the spoilers is still a work in progress (especially for spoilers in lists).
// TODO update spoiler docs to reflect new tag
```
<spoiler title="Show Solution">
- Insert OP benq solution here
</details>
```
The `summary` tag is shown. Everything below it is only shown after the user chooses to "reveal" spoilers.
The formatting of the details is **very delicate**. In particular, note the empty line after the summary tag
and before the content of the details tag. **This empty line must be indented to the beginning of the details tag.**
For example:
```
- Here's a list
- And below is a details tag in a list (which looks kind of ugly right now; hopefully it'll be fixed soon)
- <details> // Indented with two characters (a dash and a space)
<summary>Show Solution</summary> // Indented with FOUR spaces
// Indented with TWO spaces
- Insert OP benq solution here // Indented with FOUR spaces
</details>
```
### Custom Blocks
Currently, we only have one custom block (info), but others can easily be added (ex: warning, danger, error, success?).
Just let Nathan Wang know.
#### Info Block
```
[[info | Insert Title Here]]
| Insert Content Here
| **Markdown is Supported!!**
```
### Example Module
```
---
id: /intro/getting-started
title: Getting Started
author: Nathan Wang
order: 1
prerequisites:
-
- Dummy prerequisite
- https://dummy.prerequisite.link.com/
-
- Another Prerequisite
problems:
- bronze_promote
- bronze_word
- bronze_paint
- bronze_square
---
<module-excerpt>
<ul class="syllabus-only">
<li>Contest Format</li>
<li>Choosing a Language</li>
<li>Practicing and Debugging</li>
<li>Contest Strategies</li>
</ul>
</module-excerpt>
<details>
<summary>Show Solution</summary>
- Insert OP benq solution here
</details>
# Hello World!
```

View file

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2015 gatsbyjs
Copyright (c) 2020 USACO
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

150
README.md
View file

@ -8,152 +8,4 @@ All markdown files belong in `content/`. Other files are for the front-end dashb
The content should not care about how the front-end interface is implemented. That way, we can easily
change the front-end interface without having to rewrite the content.
## Content Formatting Documentation
All modules are written in [Markdown](https://www.markdownguide.org/cheat-sheet/). There are special additions to the markdown that we have added to this site.
These special additions are still under development, so they may change frequently.
If you are confused about something, or if there's a certain feature that you want to add, reach out to Nathan Wang.
You can use [StackEdit](https://stackedit.io/) to check that latex renders properly.
### Frontmatter
[Frontmatter](https://jekyllrb.com/docs/front-matter/) is the stuff in the beginning of each module that's surrounded
by three dashes. Frontmatter is written in [YAML](https://yaml.org/). It stores the "metadata" for each module.
YAML formatting is _extremely strict_. Be careful about spaces.
- **Slug**: _Required_. The URL of the module. Ex: `/intro/getting-started`, or `/bronze/containers/`
- **Title**: _Required_. The title of the module. Ex: `Getting Started`
- **Author**: _Required_. The author of the module. Ex: `Unknown`
- **Order**: _Required_. The order in which this module appears in the syllabus, **relative to its division**.
- **Prerequisites**: _Optional_. Any prerequisites for this module.
The prerequisite formatting is rather unintuitive. It expects an array of arrays, where the first item is
the name of the prerequisite, and the optional second item is a link. **Note the number of spaces!**
Example:
```
prerequisites:
-
- Prerequisite Name
- https://dummy.prerequisite.link.com/
-
- Another Prerequisite Without a Link
```
- **Problems**: _Optional_. A list of problems in the article. As we haven't figured out what we're going to do with
**it's best to not include this yet.** For USACO problems, enter each problem as `division_filename`. Ex: `bronze_promote`.
### Module Description
Everything after the frontmatter, and before this line:
```
<!-- END DESCRIPTION -->
```
is part of the "module description." It gets rendered on the homepage. Be careful not to use headers
as they will look really weird on the homepage. The module description is also included in the article itself.
If you don't want a description for the module, just put the `END DESCRIPTION` line as the first line
after the frontmatter.
If you want a description that appears only on the homepage but not the article, wrap it in
an HTML element with the class `syllabus-only`. Note that you can't use markdown in HTML elements.
Example:
```
<ul class="syllabus-only">
<li>Contest Format</li>
<li>Choosing a Language</li>
<li>Practicing and Debugging</li>
<li>Contest Strategies</li>
</ul>
<!-- END DESCRIPTION -->
```
This will render as a list in the homepage, but won't appear in the article.
### Spoilers
Spoilers are collapsible elements that only show themselves when the user clicks on it. It's useful
when writing solutions to problems. The styling of the spoilers is still a work in progress (especially for spoilers in lists).
```
<details>
<summary>Show Solution</summary>
- Insert OP benq solution here
</details>
```
The `summary` tag is shown. Everything below it is only shown after the user chooses to "reveal" spoilers.
The formatting of the details is **very delicate**. In particular, note the empty line after the summary tag
and before the content of the details tag. **This empty line must be indented to the beginning of the details tag.**
For example:
```
- Here's a list
- And below is a details tag in a list (which looks kind of ugly right now; hopefully it'll be fixed soon)
- <details> // Indented with two characters (a dash and a space)
<summary>Show Solution</summary> // Indented with FOUR spaces
// Indented with TWO spaces
- Insert OP benq solution here // Indented with FOUR spaces
</details>
```
### Custom Blocks
Currently, we only have one custom block (info), but others can easily be added (ex: warning, danger, error, success?).
Just let Nathan Wang know.
#### Info Block
```
[[info | Insert Title Here]]
| Insert Content Here
| **Markdown is Supported!!**
```
### Example Module
```
---
slug: /intro/getting-started
title: Getting Started
author: Nathan Wang
order: 1
prerequisites:
-
- Dummy prerequisite
- https://dummy.prerequisite.link.com/
-
- Another Prerequisite
problems:
- bronze_promote
- bronze_word
- bronze_paint
- bronze_square
---
<ul class="syllabus-only">
<li>Contest Format</li>
<li>Choosing a Language</li>
<li>Practicing and Debugging</li>
<li>Contest Strategies</li>
</ul>
<!-- END DESCRIPTION -->
<details>
<summary>Show Solution</summary>
- Insert OP benq solution here
</details>
# Hello World!
```
Refer to "Content Documentation.md" and "Syllabus.md" for more info.

View file

@ -1,30 +1,32 @@
---
slug: /intro/about-this
id: about-this
title: About This Guide
author: Nathan Wang, Benjamin Qi
order: 1
---
<module-excerpt>
// todo transfer all of this to the homepage
- Goals
- Module Organization
- Contact Information
<!-- END DESCRIPTION -->
</module-excerpt>
## Goals
- Intended audience: anybody in Bronze - Gold.
- We are **not** teaching people how to code (but we'll provide some links for this purpose).
- We are **not** teaching people how to code (but some resources for this purpose are provided in "Prerequisites").
- should be a "one stop shop," meaning that this is the only site they have to use.
- The idea is that people will no longer have to go resource hunting as well do all of that for them.
- For Bronze - Gold, most but not all problems on monthly contests will fall into the categories that we have designated. For Platinum, there are no guarantees.
- Note that topics may cross divisions without warning! (ex. Gold seems to have more and more tree problems that used to be confined to Platinum).
- Material will be grouped into **modules**.
- USACO-Focused: generally avoid covering topics that will not appear on USACO or IOI.
- Maybe designate some "optional" modules.
- USACO-Focused: Modules should generally stick to topics that can appear on USACO or IOI.
- "Dont Reinvent the Wheel"
- Should set guidelines as to what counts and what doesnt.
- Link to online resources that already exist.
- Should set guidelines as to what counts and what doesnt.
- Not *just* a collection of links
- There exist plenty of resources out there. While we can link to all of them, we should not expect users to click through all of them to find the information they want. This means in addition to links we need to provide information about what the link talks about, as well as the quality of the link.
- We dont want to say something like “learn DP, here are 50 links that can teach you that.” Instead, we want to say “learn DP by first reading this one article, then reading this other article. For reference, here are some other links you can explore as you wish.”
@ -38,8 +40,8 @@ order: 1
- Everything should be completed in order.
- Any problems here should be pure implementation.
- Languages
- Include C++, Java, Python for Bronze.
- Include C++, Java for Silver and beyond (C++ takes priority)
- Include C++ and Java for all divisions. (C++ takes priority)
- Possibly Python for Bronze.
### Practice

View file

@ -0,0 +1,26 @@
---
id: data-types
title: Data Types
author: Darren Yao
description: Learn about the basic data types needed for competitive programming.
---
<module-excerpt>
There are several main **data types** that are used in contests: 32-bit and 64-bit integers, floating point numbers, booleans, characters, and strings.
</module-excerpt>
## Reading
- CPH 1.1 - 1.3
The **32-bit integer** supports values between $-2\,147\,483\,648$ and $2\,147\,483\,647$, which is roughly equal to $\pm$ $2 \times 10^9$. If the input, output, or \textit{any intermediate values used in calculations} exceed the range of a 32-bit integer, then a **64-bit integer** must be used. The range of the 64-bit integer is between $-9\,223\,372\,036\,854\,775\,808$ and $9\,223\,372\,036\,854\,775\,807$ which is roughly equal to $\pm$ $9 \times 10^{18}$. Contest problems are usually set such that the 64-bit integer is sufficient. If it's not, the problem will ask for the answer modulo $m$, instead of the answer itself, where $m$ is a prime. In this case, make sure to use 64-bit integers, and take the remainder of $x$ modulo $m$ after every step using `x %= m;`.
**Floating point numbers** are used to store decimal values. It is important to know that floating point numbers are not exact, because the binary architecture of computers can only store decimals to a certain precision. Hence, we should always expect that floating point numbers are slightly off. Contest problems will accommodate this by either asking for the greatest integer less than $10^k$ times the value, or will mark as correct any output that is within a certain $\epsilon$ of the judge's answer.
**Boolean** variables have two possible states: `true` and `false`. We'll usually use booleans to mark whether a certain process is done, and arrays of booleans to mark which components of an algorithm have finished.
**Character** variables represent a single Unicode character. They are returned when you access the character at a certain index within a string. Characters are represented using the ASCII standard, which assigns each character to a corresponding integer. This allows us to do arithmetic with them; for example, both `cout << ('f' - 'a');` in C++ and `System.out.print('f' - 'a');` in Java will print `5`.
**Strings** are stored as an array of characters. You can easily access the character at a certain index and take substrings of the string. String problems on USACO Bronze or Silver generally don't involve any special data structures.

View file

@ -1,20 +1,26 @@
---
slug: /intro/problems
title: Introductory Problems
author: Nathan Wang, Benjamin Qi
id: ex-prob
title: An Example Problem
author: Nathan Wang, Benjamin Qi, Darren Yao
problems:
- bronze_promote
- bronze_word
- bronze_paint
- bronze_square
order: 5
prerequisites:
-
- Intro - Data Types
-
- Intro - Input & Output
---
Demonstrates how to read in input and print output for a USACO problem in multiple languages. Also lists some introductory USACO Bronze problems.
<module-excerpt>
<!-- END DESCRIPTION -->
Solutions for an example USACO problem in multiple languages.
[Technical Specifications for Contests](http://www.usaco.org/index.php?page=instructions)
</module-excerpt>
[Technical Specifications for USACO Contests](http://www.usaco.org/index.php?page=instructions)
## Example: [Fence Painting](http://usaco.org/index.php?page=viewproblem2&cpid=567)
@ -71,11 +77,6 @@ int main() {
### Java
(link?)
(Scanner?)
(FastScanner?)
Class name can be whatever you want. (?)
@ -93,16 +94,74 @@ public class paintSol { // must be declared in paintSol.java
st = new StringTokenizer(br.readLine());
int c = Integer.parseInt(st.nextToken()), d = Integer.parseInt(st.nextToken());
for (int i = a; i < b; ++i) cover[i] = 1;
for (int i = c; i < d; ++i) cover[i] = 1;
for (int i = a; i < b; i++) cover[i] = 1;
for (int i = c; i < d; i++) cover[i] = 1;
int ans = 0;
for (int i = 0; i < 100; ++i) ans += cover[i];
for (int i = 0; i < 100; i++) ans += cover[i];
pw.println(ans);
pw.close(); // make sure to include this line ...
pw.close(); // make sure to include this line -- flushes the output.
}
}
```
Alternatively, an InputReader class that functions very similarly to Scanner but has the faster runtime of BufferedReader.
```java
import java.util.*;
import java.io.*;
public class template {
static class InputReader {
BufferedReader reader;
StringTokenizer tokenizer;
public InputReader() throws FileNotFoundException {
reader = new BufferedReader(new FileReader("template.in"));
tokenizer = null;
}
String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
}
public static void main(String[] args) throws FileNotFoundException, IOException {
InputReader r = new InputReader();
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("template.out")));
int[] cover = new int[100];
for (int i = a; i < b; i++) cover[i] = 1;
for (int i = c; i < d; i++) cover[i] = 1;
int ans = 0;
for (int i = 0; i < 100; i++) ans += cover[i];
pw.println(ans);
pw.close(); // flush output
}
}
```
### Python 3
See [here](https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files).
@ -123,11 +182,9 @@ for i in range(100):
fout.write(str(ans))
```
## Problems
## Introductory Problems
Let's begin by solving a few problems! The following require relatively little programming experience and no algorithmic knowledge.
Do as many as you want, then move on! You do not have to do all of them.
The following require relatively little programming experience and no algorithmic knowledge. Do as many as you want, then move on! You do not have to do all of them.
- [Promotion Counting](http://usaco.org/index.php?page=viewproblem2&cpid=591)
- [Word Processor](http://usaco.org/index.php?page=viewproblem2&cpid=987)

View file

@ -0,0 +1,57 @@
---
id: getting-started
title: Getting Started
author: Nathan Wang, Benjamin Qi, Darren Yao
description: Welcome to the guide! Here we'll explain what a programming competition is, how it works, and how to choose a language.
---
<module-excerpt>
- Introduction
- Contest Format
- Choosing a Language
</module-excerpt>
## Introduction
A **programming competition** generally lasts for several hours and consists of a set of problems. These problems are not open problems; they have already been solved by the problem writer(s) and tester(s) and (hopefully) are designed to be solved in the short timeframe of a contest. In general, each problem in competitive programming is solved by a two-step process:
1. coming up with the algorithm, which involves problem solving skills and intuition
2. implementing the algorithm, which requires programming skills to translate the algorithm into working code.
For each problem, when you complete your code you submit it to a grader, which checks the answers calculated by the your program against a set of predetermined test cases. For each problem, you are given a time limit (usually 2 seconds) and a memory limit (usually 256 megabytes) that your program must satisfy.
For those of you with experience in software development, note that competitive programming is quite different, as the goal is to write programs that compute the correct answer, run quickly, and can be implemented quickly. Note that nowhere was maintainability of code mentioned. So you don't need to bother documenting your code because it only needs to be readable to you during the contest.
### Videos
- [William Lin - What is Competitive Programming?](https://www.youtube.com/watch?time_continue=1&v=ueNT-w7Oluw)
- [Kamil Debowski - Interview with a Competitive Programmer](https://www.youtube.com/watch?v=F4rykKLcduI)
- [Example Problem](https://open.kattis.com/contests/mcpc19open/problems/basketballoneonone)
## Contest Format
The [USA Computing Olympiad](http://www.usaco.org/index.php?page=contests) is a national programming competition that occurs four times a year, with December, January, February, and US Open (March) contests. The regular contests are four hours long, and the US Open is five hours long. Each contest contains three problems. Solutions are evaluated and scored against a set of predetermined test cases that are not visible to the student. Scoring is out of 1000 points, with each problem being weighted equally (\~333 points). There are four divisions of contests: Bronze, Silver, Gold, and Platinum. After each contest, students who meet the contest-dependent cutoff for promotion will compete in the next division for future contests.
## Choosing a Language
If you're in Bronze, **don't worry about the language!** If you already know a language, just use it.
In general, we recommend the following:
- For Bronze contestants, any of C++/Java/Python will do.
- If you know multiple languages, we recommend you pick C++ over Java, and Java over Python.
- For Silver, Gold, and Platinum, we recommend C++/Java.
- If you know multiple languages, we recommend you pick C++ over Java.
A majority of high level contestants use C++ and Java. Between those, C++ is more popular. Keep in mind that it's easy to switch languages down the road! Don't get caught up on which language to choose. Just pick the one you feel most comfortable with!
### Language References
All of these are provided at the IOI aside from the additional C++ reference.
- [C++](https://en.cppreference.com/w/)
- [Additional C++ Reference](http://www.cplusplus.com/)
- [Java](https://docs.oracle.com/javase/8/docs/api/overview-summary.html)
- [Python3](https://docs.python.org/3/reference/)

View file

@ -0,0 +1,183 @@
---
id: io
title: Input & Output
author: Darren Yao
---
<module-excerpt>
Demonstrates how to read input and print output for USACO.
</module-excerpt>
## C++
In CodeForces and CSES, input and output are **standard**, meaning that using the library [\<iostream\>](http://www.cplusplus.com/reference/iostream/) suffices.
However, in USACO, input is read from a file called `problemname.in`, and printing output to a file called `problemname.out`. Note that you'll have to rename the `.in` and `.out` files. You will need the [\<cstdio\>](http://www.cplusplus.com/reference/cstdio/) or the [\<fstream\>](http://www.cplusplus.com/reference/fstream/) library. Essentially, replace every instance of the word *template* in the word below with the input/output file name, which should be given in the problem.
In order to test a program, create a file called `problemname.in`, and then run the program. The output will be printed to `problemname.out`.
Below, we have included C++ templates for input and output. We use `using namespace std;` so that we don't have to preface standard library functions with `std::` each time we use them.
If `<cstdio>` is used:
```cpp
#include <cstdio>
using namespace std;
int main() {
freopen("template.in", "r", stdin);
freopen("template.out", "w", stdout);
}
```
If `<fstream>` is used (note that if you use `<fstream>`, you must replace `cin` and `cout` with `fin` and `fout`):
```cpp
#include <fstream>
using namespace std;
int main() {
ifstream fin("template.in");
ofstream fout("template.out");
}
```
For CodeForces, CSES, and other contests that use standard input and output, simply use the standard input / output from `<iostream>`.
## Java
In your CS classes, you've probably implemented input and output using standard input and standard output, or using `Scanner` to read input and `System.out.print` to print output.
In CodeForces and CSES, input and output are standard, and the above methods work. However, `Scanner` and `System.out.print` are slow when we have to handle inputting and outputting tens of thousands of lines. Thus, we use `BufferedReader` and `PrintWriter` instead, which are faster because they buffer the input and output and handle it all at once as opposed to parsing each line individually.
However, in USACO, input is read from a file called `problemname.in`, and printing output to a file called `problemname.out`. Note that you'll have to rename the `.in` and `.out` files. Essentially, replace every instance of the word *template* in the word below with the input/output file name, which should be given in the problem.
In order to test a program, create a file called `problemname.in`, and then run the program. The output will be printed to `problemname.out`.
Below, we have included Java templates for input and output, which are effectively faster Scanners. We import the entire `util` and `io` libraries for ease of use.
```java
import java.util.*;
import java.io.*;
public class template {
static class InputReader {
BufferedReader reader;
StringTokenizer tokenizer;
public InputReader() throws FileNotFoundException {
reader = new BufferedReader(new FileReader("template.in"));
tokenizer = null;
}
String next() { // reads in the next String
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() { // reads in the next int
return Integer.parseInt(next());
}
public long nextLong() { // reads in the next long
return Long.parseLong(next());
}
public double nextDouble() { // reads in the next double
return Double.parseDouble(next());
}
}
public static void main(String[] args) throws FileNotFoundException, IOException {
InputReader r = new InputReader();
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("template.out")));
// YOUR CODE HERE
pw.close(); // flushes the output once printing is done
}
}
```
For CodeForces, CSES, and other contests that use standard input and output, the template is as follows:
```java
import java.io.*;
import java.util.*;
public class template {
static class InputReader {
BufferedReader reader;
StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
String next() { // reads in the next string
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() { // reads in the next int
return Integer.parseInt(next());
}
public long nextLong() { // reads in the next long
return Long.parseLong(next());
}
public double nextDouble() { // reads in the next double
return Double.parseDouble(next());
}
}
static InputReader r = new InputReader(System.in);
static PrintWriter pw = new PrintWriter(System.out);
public static void main(String[] args) {
// YOUR CODE HERE
pw.close(); // flushes the output once printing is done
}
}
```
Here's a brief description of the methods in our `InputReader` class, with an instance `r`, and `PrintWriter` with an instance `pw`.
(insert table)
Here's an example to show how input/output works. Let's say we want to write a program that takes three numbers as input and prints their sum.
```java
// InputReader template code above
static InputReader r = new InputReader(System.in);
static PrintWriter pw = new PrintWriter(System.out);
public static void main(String[] args) {
int a = r.nextInt();
int b = r.nextInt();
int c = r.nextInt()
pw.println(a + b + c);
pw.close();
}
```

View file

@ -1,54 +0,0 @@
---
slug: /intro/getting-started
title: Getting Started
author: Nathan Wang, Benjamin Qi
order: 2
---
- Introduction
- Contest Format
- Choosing a Language
<!-- END DESCRIPTION -->
Todo:
- Video clip from Brian Dean?
- Explains what USACO is all about & how it works
## Introduction
In competitive programming contests, one must solve well-defined problems by writing computer programs under specified constraints ([Wikipedia](https://en.wikipedia.org/wiki/Competitive_programming)). Typically, the most popular language is C++, followed by Java and Python.
[William Lin - What is Competitive Programming?](https://www.youtube.com/watch?time_continue=1&v=ueNT-w7Oluw)
## Contest Format
(todo)
See [USACO contests](http://www.usaco.org/index.php?page=contests).
## Choosing a Language
If you're in Bronze, **don't worry about the language!** If you already know a language, just use it. You can always switch languages down the road.
In general, we recommend the following:
- For Bronze contestants, any of C++/Java/Python will do.
- If you know multiple languages, we recommend you pick C++ over Java, and Java over Python.
- For Silver, Gold, and Platinum, we recommend C++/Java.
- If you know multiple languages, we recommend you pick C++ over Java.
Note: A majority of high level contestants use C++ and Java. Between those, C++ is more popular.
Keep in mind that it's easy to switch languages down the road! Don't get caught up on which language to choose. Just pick the one you feel most comfortable with!
### Language References
All of these are provided at the IOI asside from the additional C++ reference.
- [C++](https://en.cppreference.com/w/)
- [Additional C++ Reference](http://www.cplusplus.com/)
- [Java](https://docs.oracle.com/javase/8/docs/api/overview-summary.html)
- [Python3](https://docs.python.org/3/reference/)

View file

@ -0,0 +1,104 @@
---
id: practicing
title: How to Practice
author: Many
---
<module-excerpt>
How to practice, when to read editorials (analyses), etc.
</module-excerpt>
Knowing when to "give up" on a problem and start reading the problem's editorial is challenging. Below are the opinions of various individuals. Note that "give up" is in quotes, because one still learns when they "give up" and read an editorial!
## Darren Yao (Intro to USACO 1.3)
Reaching a high level in competitive programming requires dedication and motivation. For many people, their practice is inefficient because they do problems that are too easy, too hard, or simply of the wrong type.
In the lower divisions, most problems use relatively elementary algorithms; the main challenge is deciding which algorithm to use, and implementing it correctly. In a contest, you should spend the bulk of your time thinking about the problem and coming up with the algorithm, rather than typing code. Thus, you should practice your implementation skills, so that during the contest, you can implement the algorithm quickly and correctly, without resorting to debugging.
In general, I think its fine to read the solution relatively early on, as long as youre made several different attempts at it and you can learn effectively from the solution.
- On a bronze problem, read the solution after 15-20 minutes of no meaningful progress, after youve exhausted every idea you can think of.
- On a silver problem, read the solution after 30-40 minutes of no meaningful progress.
- IMPORTANT: When you get stuck and consult the solution, you should not read the entire solution at once, and you certainly shouldnt look at the solution code. Instead, its better to read the solution step by step until you get unstuck, at which point you should go back and finish the problem, and implement it yourself. Reading the full solution or its code should be seen as a last resort.
Problems that you practice with should be of the appropriate difficulty. You don't necessarily need to complete all the exercises at the end of each module, just do what you think is right for you. A problem at the right level of difficulty should be one of two types: either you struggle with the problem for a while before coming up with a working solution, or you miss it slightly and need to consult the solution for some small part. If you instantly come up with the solution, a problem is likely too easy, and if you're missing multiple steps, it might be too hard.
[This](https://web.evanchen.cc/FAQs/raqs.html) and [this](https://usamo.wordpress.com/2019/01/31/math-contest-platitudes-v3/) are two blog posts by Evan Chen that I find quite insightful. They discuss such things as time management, the problem-solving process, and other tips that you may find useful.
## Nathan Wang
My personal opinion is that it is okay to give up early when solving CP problems.
Sometimes I spend as little as 15-20 minutes on a problem before reading the editorial
or at least glancing at solution code. Other times I may spend significantly longer.
CP editorials generally aren't the best (with the exception of USACO editorials,
which are pretty good) so I often spend a lot of time trying to understand the
solution even after "giving up" and reading the editorial. I think it's good
enough to implement the code without having the editorial open.
My justification for why I think it's okay to give up so early is as follows:
- Getting frustrated and quitting CP for a week is worse than giving up
- Whenever I feel like I'm really frustrated with a problem, I read the editorial
- CP editorials are usually difficult to understand, so you will still have
to spend a lot of time reading and understanding them
- You learn a _lot_ by reading editorials
- If you can solve a problem without reading the editorial, that means you
probably could have solved the problem in-contest too, so you didn't actually
learn that much. However, if you didn't know how to solve a problem and
you read the editorial so now you do, then you've learned a lot more.
- In other words, reading editorials is a _good_ thing, not a bad thing!
Overall, I would just say to "give up" when you feel like giving up, whether that's
in five hours or in 15 minutes :)
## Siyong Huang
There are two ways to grow from solving a problem:
### 1 - You learn a new idea/algorithm from it.
You learn ideas from problems you cannot solve. This means that you *need* to read an editorial or someone else's accepted solution. Please try to understand the editorial; it's an important skill to have. You should be re-reading it multiple times and walking through various examples. If this fails, read someone's accepted solution (try to find one that is easy to read, if possible) and figure out what it is doing. If even this doesn't work, ask the author of the solution to explain their logic or specific parts of their code. Trust me, many are extremely happy to help someone who has made an effort to understand the editorial and has used their code as reference.
Furthermore, there have been countless cases where people have asked for help before reading the editorial. We will just link the editorial or repeat it for them, which is pointless.
Finally, hints are extremely overrated in my opinion. Just read the whole solution. You don't gain anything from reading part of a solution then finishing it out yourself. As long as you implement it in the end, you are still learning the same thing.
### 2 - Your implementation speed and consistency improves.
The best way to do this is to solve a bunch of easy or moderate difficulty problems. Try to solve them as fast as possible, as if you were in a contest. Perhaps take virtuals or time yourself when solving problems. Whichever you choose, the more problems you solve, the better you will become.
## Benjamin Qi
If you're still coming up with new ideas, keep thinking. Otherwise, you have several options:
- Look at [part of] the solution. (If CodeForces, look at the tags.)
- Leave it for a while and do something else if you actually want to solve it on your own.
- Get a hint from someone else.
I'm impatient, so usually I go with the first option. Sometimes I end up reading an editorial before reading the statement, but idk if this is a good strategy. :/
In any case, if you thought about a problem a lot during a contest but didn't end up solving it, then I don't see any reason not to read the editorial when it comes out (vs. continuing to think about it on your own). Also, you should always implement the solution afterwards!
## Nathan Chen
Read the editorial when you feel like you've stopped making progress; that could be from 1 to 5 hours. However, the most important part about reading the editorial is that you understand the topic and try to think about what similar problems look like. Being generally curious is a good way to practice algorithmic thinking.
## William Lin
I follow three guidelines (from most important to least important)
1. Having fun, just doing whatever you feel like doing
2. Spend about the same amount of time that you would be able to during a real contest
3. Whether you are making progress or not
## Eric Wei
I think the most important thing regarding practicing is to try to get something out of every problem, whether it's a new algorithm or idea, an implementation trick that can help in the future, or just a bug you hopefully won't mess up in the future. That being said, editorials are more useful once you've been stuck for a while; I think the exploration that happens from being a little stuck is often instructive (and good practice for contests, when it's your only option). But at some point the problem's more frustrating than helpful, and sometime before this is probably the right time to take a hint or read the editorial.
## Additional
- [E869120 - A Way to Practice CP](http://codeforces.com/blog/entry/53341)

View file

@ -1,13 +1,14 @@
---
slug: /intro/prerequisites
id: prereqs
title: Prerequisites
author: Nathan Wang
order: 3
author: Nathan Wang, Benjamin Qi
---
<module-excerpt>
Here's what you should learn before reading these resources.
<!-- END DESCRIPTION -->
</module-excerpt>
These resources do **not** teach you how to code. We recommend you learn roughly the first half of AP Computer Science A before continuing. If you do not meet these prerequisites, you can go to the resources below to get started.
@ -38,9 +39,12 @@ Familiarity with [competition math](https://github.com/bqi343/USACO/blob/master/
### Resources for Getting Started
Note: We don't agree with all views expressed in the links below. Feel free to let us know what works (or doesn't) for you.
- [CodeSignal](https://codesignal.com/)
- good place to practice basics
- [IOI: Getting Started](https://ioinformatics.org/page/getting-started/14)
- can practice basics with "Arcade," "Interview Practice"
- [Philippines OI: Prepare](https://noi.ph/prepare/)
- [Schedule for Beginners](https://www.quora.com/What-is-a-good-schedule-to-follow-for-becoming-better-at-competitive-programming-for-beginners)
- [E869120 Tutorial](http://codeforces.com/blog/entry/53341)
- lots of links!
- [IOI - Getting Started](https://ioinformatics.org/page/getting-started/14)
- not so up to date
- [Quora - Schedule for Beginners (Joshua Pan)](https://www.quora.com/What-is-a-good-schedule-to-follow-for-becoming-better-at-competitive-programming-for-beginners)

View file

@ -1,39 +1,40 @@
---
slug: /intro/running-cpp
id: running-cpp
title: Running C++
author: Nathan Wang, Benjamin Qi, Anthony Wang
order: 4
---
<module-excerpt>
Running C++ both online and locally.
<!-- END DESCRIPTION -->
</module-excerpt>
# Running C++ Online
* [OnlineGDB](https://www.onlinegdb.com/)
* online compiler with an embedded GDB debugger
* can be buggy sometimes
* supports files and file I/O
* [CSAcademy](https://csacademy.com/workspace/)
* pretty nice (unless you get "Estimated Queue Time: ...")
* "saved locally" will not save your code if you close the tab, press Command-S to save.
* [Ideone](http://ideone.com/)
* okay ... with an ad blocker
* make sure your code is not public
* sometimes erases your code when you first create it (so get in the habit of copying your code first)
- [OnlineGDB](https://www.onlinegdb.com/)
- online compiler with an embedded GDB debugger
- can be buggy sometimes
- supports files and file I/O
- [CSAcademy](https://csacademy.com/workspace/)
- pretty nice (unless you get "Estimated Queue Time: ...")
- "saved locally" will not save your code if you close the tab, press Command-S to save.
- [Ideone](http://ideone.com/)
- okay ... with an ad blocker
- make sure your code is not public
- sometimes erases your code when you first create it (so get in the habit of copying your code first)
Of course, you can't use file I/O on the latter two websites and they are often quite limited.
Of course, you can't use file I/O on the latter two websites.
# Running C++ Locally
## On Mac
[Clang](https://en.wikipedia.org/wiki/Clang) is the default compiler for Mac OS X, but you should use GCC's [g++](https://en.wikipedia.org/wiki/GNU_Compiler_Collection).
[Clang](https://en.wikipedia.org/wiki/Clang) is the default compiler for Mac OS X, but you should use [GCC](https://en.wikipedia.org/wiki/GNU_Compiler_Collection)'s g++.
### Installation
Open **Terminal**. First, familiarize yourself with some basic commands given [here](https://blog.teamtreehouse.com/introduction-to-the-mac-os-x-command-line). You will also need to install [Homebrew](https://brew.sh/).
First, Open **Terminal**. Familiarize yourself with some basic commands given [here](https://blog.teamtreehouse.com/introduction-to-the-mac-os-x-command-line). You will also need to install [Homebrew](https://brew.sh/).
Run
@ -182,28 +183,32 @@ Note that all occurrences of `$1` are replaced with `name`.
## IDEs
* [Geany](https://www.geany.org/)
* [Visual Studio Code](https://code.visualstudio.com/)
* lightweight, fast IDE, but requires some configuration
* [Visual Studio](https://visualstudio.microsoft.com/vs/)
* heavier cousin of Visual Studio Code
* [XCode](https://developer.apple.com/xcode/)
* Mac only
* [Codeblocks](http://www.codeblocks.org/)
* bad on Mac
* [CLion](https://www.jetbrains.com/clion/)
* requires a license, but [free for students](https://www.jetbrains.com/community/education/#students)
- [Geany](https://www.geany.org/)
- [Visual Studio Code](https://code.visualstudio.com/)
- lightweight, fast IDE, but requires some configuration
- [Visual Studio](https://visualstudio.microsoft.com/vs/)
- heavier cousin of Visual Studio Code
- [XCode](https://developer.apple.com/xcode/)
- Mac only
- [Codeblocks](http://www.codeblocks.org/)
- bad on Mac
- [CLion](https://www.jetbrains.com/clion/)
- requires a license, but [free for students](https://www.jetbrains.com/community/education/#students)
## Text Editors
Again, many options.
* [Sublime Text 3](https://www.sublimetext.com/) - a fast, lightweight text editor for Windows, Mac, and Linux
* [Editing Build Settings](https://stackoverflow.com/questions/23789410/how-to-edit-sublime-text-build-settings)
* [FastOlympicCoding Addon](https://github.com/Jatana/FastOlympicCoding)
* [Sublime Snippets](https://www.granneman.com/webdev/editors/sublime-text/top-features-of-sublime-text/quickly-insert-text-and-code-with-sublime-text-snippets)
* [Symlink](https://www.sublimetext.com/docs/3/osx_command_line.html)
* Using `/usr/local/bin/subl` instead of `~/bin/subl` worked for me on OS X Mojave.
* [Atom](https://atom.io/) - another text editor for Windows, Mac, and Linux, from the makers of Github
* [Vim](https://www.vim.org/) - the classic text editor, usually preinstalled on Mac and Linux, and also available for Windows
* Others?
- [Sublime Text 3](https://www.sublimetext.com/)
- a fast, lightweight text editor for Windows, Mac, and Linux
- [Editing Build Settings](https://stackoverflow.com/questions/23789410/how-to-edit-sublime-text-build-settings)
- [FastOlympicCoding Addon](https://github.com/Jatana/FastOlympicCoding)
- [Sublime Snippets](https://www.granneman.com/webdev/editors/sublime-text/top-features-of-sublime-text/quickly-insert-text-and-code-with-sublime-text-snippets)
- [Symlink](https://www.sublimetext.com/docs/3/osx_command_line.html)
- Using `/usr/local/bin/subl` instead of `~/bin/subl` worked for me on OS X Mojave.
- [Atom](https://atom.io/)
- another text editor for Windows, Mac, and Linux, from the makers of Github
- [Vim](https://www.vim.org/)
- the classic text editor, usually preinstalled on Mac and Linux, and also available for Windows
- probably easiest way to print syntax-highlighted code on Mac, see [here](https://stackoverflow.com/questions/1656914/printing-code-with-syntax-highlighting)
- Others?

View file

@ -1,106 +0,0 @@
---
slug: /general/contests
title: Contests
author: Benjamin Qi
order: 2
---
Contests that I participate in, as well as a few tools.
<!-- END DESCRIPTION -->
See [clist.by](https://clist.by/coder/bqi343/) for an extensive list. Most of the contests which I do are a subset of those shown in "Programming Contests.png". A link to my google calendar for contests is available [here.](https://calendar.google.com/calendar?cid=Y2s5ZjdmZDBkNjdmOGFxZ2oxbDVrMHJ1OGtAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ) See the other page for olympiads such as USACO.
Make sure to [upsolve](https://en.wiktionary.org/wiki/upsolve) after the contest ends! I particularly enjoy problems from AtCoder and CSAcademy. :)
* [AtCoder](https://beta.atcoder.jp/contests/archive)
* Contests
* Beginner / Regular: 4 problems, 100 min
* Grand: 6 problems, ~110 min
* [Visualizer](https://kenkoooo.com/atcoder/#/table/Benq)
* I've done nearly all of the AGC problems.
* [Codeforces](http://codeforces.com/problemset)
* Contests
* Div 2, Div 1: 5 problems, 2 hrs
* Archive
* problem quality, difficulty ratings are ok but not always great
* [Topcoder](https://www.topcoder.com/my-dashboard/)
* Div 2, Div 1
* 75 min coding, 15 min challenge
* Solutions only tested after contest!
* [Don Mills OJ](http://dmoj.ca/)
* at least one contest every month during school year
* [Google Kickstart](https://codingcompetitions.withgoogle.com/kickstart)
* Feb - Nov
* [Kattis](https://open.kattis.com/)
* random ICPC stuff
* [HackerEarth](http://hackerearth.com/)
* Monthly "Easy"
* quality is not always good
* [Codechef](http://codechef.com/)
* Lunchtime, Cookoff
* quality is not always good
The following websites do not hold regular contests anymore, but they're still worth looking at.
* [CS Academy](https://csacademy.com/contest/archive/)
* Contests
* Div 2: 5 problems, 2 hrs
* Open: 7 problems, 2 hrs
* no more? D:
* Archive
* short statements, editorials
* solve statistics
* ability to view best solutions
* I've done nearly all of the problems. :D
* [HackerRank](https://www.hackerrank.com/dashboard)
## Annual Contests
* [Google Code Jam](https://code.google.com/codejam/): Apr
* 25 from R3
* [Facebook Hacker Cup](https://www.facebook.com/hackercup/): Jun-Jul -> Oct??
* 25 from R3
* [Topcoder Open](https://tco19.topcoder.com/): Apr-Aug -> Nov
* 4 from SRMs
* 10 from R4
* 2 from Wildcard
* [AtCoder World Tour Finals](https://codeforces.com/blog/entry/56623)
* 8 from AGC
* [Bubble Cup](http://bubblecup.org/): Apr
## US High School
* [VT HSPC](https://icpc.cs.vt.edu/#/hscontest2017)
* Online
* 5 hours
* [Kattis](https://open.kattis.com/problem-sources/2016%20Virginia%20Tech%20High%20School%20Programming%20Contest)
* December
* [UCF HSPT](https://hspt.ucfprogrammingteam.org/index.php/hspt-online-edition)
* Online
* 4 hours
* December
* [Cornell HSPC](https://www.cs.cornell.edu/events/cornell-high-school-programming-contest)
* [2019](https://cornell-hspc19.kattis.com/problems)
* [PClassic (Philadelphia)](https://pclassic.org/)
* Java only :((
* [mBIT (Montgomery Blair HS)](https://mbit.mbhs.edu/)
## 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)
* [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/)

View file

@ -1,74 +0,0 @@
---
slug: /general/practicing
title: How to Practice
author: Benjamin Qi, William Lin, Eric Wei, Nathan Wang, Nathan Chen
order: 4
---
How to practice, when to read editorials (analyses), etc.
<!-- END DESCRIPTION -->
## Practicing
## Reading Editorials
Knowing when to "give up" on a problem and start reading the problem's editorial
is challenging. Below are the opinions of various individuals.
Note that "give up" is in quotes, because one still learns when they "give up" and read an editorial!
### Benjamin Qi
If you're still coming up with new ideas, keep thinking. Otherwise, you have several options:
- Look at [part of] the solution. (If CodeForces, look at the tags.)
- Leave it for a while and do something else if you actually want to solve it on your own.
- Get a hint from someone else.
I'm impatient, so usually I go with the first option. Sometimes I end up reading an editorial before reading the statement, but idk if this is a good strategy. :/
In any case, if you thought about a problem a lot during a contest but didn't end up solving it, then I don't see any reason not to read the editorial when it comes out (vs. continuing to think about it on your own). Also, you should always implement the solution afterwards!
### William Lin
> I follow three guidelines (from most important to least important)
> 1. Having fun, just doing whatever you feel like doing
> 2. Spend about the same amount of time that you would be able to during a real contest
> 3. Whether you are making progress or not
Feel free to not listen to William Lin's suggestions as he is not very good himself.
### Eric Wei
> read problem editorials some time after thinking "i have no clue what i'm doing please send help" and before "if i stare at this problem for one minute longer i'm going to punch a hole in my computer", figure out the exact time yourself
### Nathan Wang
My personal opinion is that it is okay to give up early when solving CP problems.
Sometimes I spend as little as 15-20 minutes on a problem before reading the editorial
or at least glancing at solution code. Other times I may spend significantly longer.
CP editorials generally aren't the best (with the exception of USACO editorials,
which are pretty good) so I often spend a lot of time trying to understand the
solution even after "giving up" and reading the editorial. I think it's good
enough to implement the code without having the editorial open.
My justification for why I think it's okay to give up so early is as follows:
- Getting frustrated and quitting CP for a week is worse than giving up
- Whenever I feel like I'm really frustrated with a problem, I read the editorial
- CP editorials are usually difficult to understand, so you will still have
to spend a lot of time reading and understanding them
- You learn a _lot_ by reading editorials
- If you can solve a problem without reading the editorial, that means you
probably could have solved the problem in-contest too, so you didn't actually
learn that much. However, if you didn't know how to solve a problem and
you read the editorial so now you do, then you've learned a lot more.
- In other words, reading editorials is a _good_ thing, not a bad thing!
Overall, I would just say to "give up" when you feel like giving up, whether that's
in five hours or in 15 minutes :)
### Nathan Chen
Read the editorial when you feel like you've stopped making progress; that could be from 1 to 5 hours. However, the most important part about reading the editorial is that you understand the topic and try to think about what similar problems look like. Being generally curious is a good way to practice algorithmic thinking.

View file

@ -1,6 +0,0 @@
---
slug: /general/strategy
title: Contest Strategy
author: ?
order: 5
---

View file

@ -0,0 +1,51 @@
---
id: contest-strategy
title: Contest Strategy
author: Nathan Chen
---
The best contest strategy is to go in knowing everything. However, only few people can do this, see [BenQ](https://codeforces.com/profile/benq) or [TMW](https://codeforces.com/profile/tmwilliamlin168). (I kid).
<!-- END DESCRIPTION -->
Once the timer starts, there's no more studying you can do, and managing your time wisely is the best thing you can do to maximize your score.
## Strategy
Below are some general ideas on how to strategize during a contest.
Strategy is flexible and all advice should be taken with a grain of salt. Strategy should be personal to *you* specifically.
### The beginning of a contest
You should read *all* the problems first (don't give up on any problems prematurely). Generally, a lot of thinking should happen before any coding. Depending on the difficulty of a contest, you can spend anywhere from 5 minutes to 2 hours with a pencil and paper before touching the keyboard.
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.
### Time allocation
It's the worst feeling in the world to sink 4 hours into a problem and not get it, only for another problem to have an easier solution. 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.
### When you see a solution
If you immediately get the solution to a problem while reading it, it might be a good idea to code it up quickly and get it out of the way.
It also might be a good idea to make some progress on other problems before coding the one you know how to do. When you come back and start coding, you can make sure your solution still makes sense and then you have ideas from the other problems bouncing around in your head while you're coding.
### When there are partials
If you can get points from partially solving a problem (e.g. in USACO), then it's a good idea to keep those subtasks in mind. There are two main approaches to partially solving problems.
- Use most of your time to think about the full problem, then code the partials if you haven't found the solution and your time will soon run out.
- If you find the full solution, be certain your solution is correct, lest you waste an hour coding something completely wrong.
- Judge the difficulty of the partials carefully! It could take anywhere from 30 seconds to 30 minutes to code a partial, or maybe a partial wasn't as trivial as you thought!
- Work up from the partials, coding the easiest and then going to the hardest. The partial subtasks may help you think of the full solution, and will also help you stay on track.
## Personal Commentaries
### Nathan Chen
At the Platinum level, I first read everything and then I usually spend the first hour thinking about the easiest two problems (the hardest problem is usually VERY hard). I continue thinking for the rest of the contest window and I code them if I think I have the solution. I'm also the type to save partials for last, when time is running out and I still have nothing.
### Benjamin Qi
Do the partials you can; hopefully by then you've figured out the full solution. :D

View file

@ -0,0 +1,108 @@
---
id: contests
title: Contests
author: Benjamin Qi
---
<module-excerpt>
Contests that I participate in, as well as a few tools.
</module-excerpt>
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!
- [AtCoder](https://beta.atcoder.jp/contests/archive)
- probably the highest quality, although difficulty isn't always reasonable
- Contests
- Beginner / Regular: 4 problems, 100 min
- Grand: 6 problems, ~110 min
- [Visualizer](https://kenkoooo.com/atcoder/#/table/Benq)
- I've done nearly all of the AGC problems.
- [Codeforces](http://codeforces.com/problemset)
- Contests
- Div 2, Div 1: 5 problems, 2 hrs
- Archive
- problem quality, difficulty ratings are ok but not always great
- [Topcoder](https://www.topcoder.com/my-dashboard/)
- Div 2, Div 1
- 75 min coding, 15 min challenge
- Solutions only tested after contest!
- [Don Mills OJ](http://dmoj.ca/)
- at least one contest every month during school year
- [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
The following websites do not hold regular contests anymore, but they're still worth looking at.
- [CS Academy](https://csacademy.com/contest/archive/)
- Contests
- Div 2: 5 problems, 2 hrs
- Open: 7 problems, 2 hrs
- no more? D:
- Archive
- short statements, editorials
- solve statistics
- ability to view best solutions
- I've done nearly all of the problems. :D
- [HackerRank](https://www.hackerrank.com/dashboard)
## Annual Contests
- [Google Code Jam](https://code.google.com/codejam/): Apr
- 25 from R3
- [Facebook Hacker Cup](https://www.facebook.com/hackercup/): Jun-Jul -> Oct??
- 25 from R3
- [Topcoder Open](https://tco19.topcoder.com/): Apr-Aug -> Nov
- 4 from SRMs
- 10 from R4
- 2 from Wildcard
- [AtCoder World Tour Finals](https://codeforces.com/blog/entry/56623)
- 8 from AGC
- [Bubble Cup](http://bubblecup.org/): Apr
## US High School
- [VT HSPC](https://icpc.cs.vt.edu/#/hscontest2017)
- Online
- 5 hours
- [Kattis](https://open.kattis.com/problem-sources/2016%20Virginia%20Tech%20High%20School%20Programming%20Contest)
- December
- [UCF HSPT](https://hspt.ucfprogrammingteam.org/index.php/hspt-online-edition)
- Online
- 4 hours
- December
- [Cornell HSPC](https://www.cs.cornell.edu/events/cornell-high-school-programming-contest)
- [2019](https://cornell-hspc19.kattis.com/problems)
- [PClassic (Philadelphia)](https://pclassic.org/)
- Java only :((
- [mBIT (Montgomery Blair HS)](https://mbit.mbhs.edu/)
## 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)
- [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/)

View file

@ -1,17 +1,18 @@
---
slug: /general/debugging
id: debugging
title: Debugging
author: Benjamin Qi, Aaron Chew
order: 6
---
<module-excerpt>
Detecting issues within your program and figuring out how to avoid them in the first place.
<!-- END DESCRIPTION -->
</module-excerpt>
## Style Guide
[Swift](https://codeforces.com/blog/entry/64218)
[Competitive C++ Manifesto: A Style Guide](https://codeforces.com/blog/entry/64218)
## Compilation
@ -28,6 +29,8 @@ See [here](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html).
`-Wall -Wextra -Wshadow`
[Variable shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) should be avoided whenever possible.
### Stack Size
According to [this comment](https://codeforces.com/blog/entry/60999?#comment-449312), `-Wl,-stack_size -Wl,0xF0000000` increases the stack size on Mac (otherwise, you might get a runtime error).
@ -76,11 +79,9 @@ In essense, a debugger is a tool to "trace code" for you. It is not much differe
Pros of using a debugger:
- No need to write print statements so you save time
- You can step through the code in real time
Cons of using a debugger:
- You cannot see the overall "output" of your program at each stage. For example, if I wanted to see the every single value of `i` in the program, I could not using a debugger.
- You cannot see the overall "output" of your program at each stage. For example, if I wanted to see every single value of `i` in the program, I could not using a debugger.
- Most advanced competitive programmers do not use debuggers; it is quite time inefficient.

View file

@ -1,13 +1,14 @@
---
slug: /general/macros
id: macros
title: C++ Macros
author: Benjamin Qi
order: 7
---
Shortening code and making it more (un?)readable.
<module-excerpt>
<!-- END DESCRIPTION -->
Shortening code and making it (un?)readable.
</module-excerpt>
## Introduction
@ -75,7 +76,7 @@ Most USACO problems satisfy $N\le 2\cdot 10^5$.
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
```
See [neal's blog](https://codeforces.com/blog/entry/61587) about why `rand()` is bad. Uuse `rng()` instead.
See [neal's blog](https://codeforces.com/blog/entry/61587) about why `rand()` is bad. Use `rng()` instead.
### ckmin

View file

@ -0,0 +1,72 @@
---
id: proposing
title: Proposing Problems for USACO Monthlies
author: Benjamin Qi
---
<module-excerpt>
Anyone can propose problems for monthly contests.
</module-excerpt>
Email your proposal to Professor Dean. In the [past](http://www.usaco.org/index.php?page=viewproblem2&cpid=817), contestants have even written problems for their own divisions!
- All problems should have 10 test cases at minimum (I believe that the maximum was 21 for [valleys](http://www.usaco.org/index.php?page=viewproblem2&cpid=950)). You do not need to include these in your proposal.
- All statements must eventually be converted to the following format. It's not required, but please save us time by following it as best you can.
<spoiler title="2020 Open Gold - Favorite Colors">
```
http://www.usaco.org/index.php?page=viewproblem2&cpid=1042
bolded text should be surrounded by [b][/b], italics by [i][/i]
use [ol][/ol] for numbered list
---
Each of Farmer John's $N$ cows ($1\le N\le 2\cdot 10^5$) has a favorite color.
The cows are conveniently labeled $1\ldots N$ (as always), and each color can be
represented by an integer in the range $1\ldots N$.
There exist $M$ pairs of cows $(a,b)$ such that cow $b$ admires cow $a$
($1\le M\le 2\cdot 10^5$). It is possible that $a=b$, in which case a cow
admires herself. For any color $c$, if cows $x$ and $y$ both admire a cow with
favorite color $c$, then $x$ and $y$ share the same favorite color.
Given this information, determine an assignment of cows to favorite colors such
that the number of distinct favorite colors among all cows is maximized. As
there are multiple assignments that satisfy this property, output the
lexicographically smallest one (meaning that you should take the assignment that
minimizes the colors assigned to cows $1\ldots N$ in that order).
[input]
The first line contains $N$ and $M$.
The next $M$ lines each contain two space-separated integers $a$ and $b$
($1\le a,b\le N$), denoting that cow $b$ admires cow $a$. The same pair may
appear more than once in the input.
[/input]
[output]
For each $i$ in $1\ldots N$, output the color of cow $i$ in the desired
assignment on a new line.
[/output]
[example]
In the attached image, the circles with bolded borders represent the cows with
favorite color 1.
[section|SCORING:]
[ul]
[li]Test cases 2-3 satisfy $N,M\le 10^3$. [/li]
[li]Test cases 4-10 satisfy no additional constraints. [/li]
[/ul]
[/section]
```
</spoiler>

View file

@ -1,13 +1,14 @@
---
slug: /general/resources
id: resources
title: Additional Resources
author: Benjamin Qi
order: 1
---
Helpful Links! Some (such as CPH and Intro to USACO) will be mentioned again in later modules.
<module-excerpt>
<!-- END DESCRIPTION -->
Helpful Links! Some (such as **CPH** and **Intro to USACO**) will be mentioned again in later modules.
</module-excerpt>
## Lists

View file

@ -1,23 +1,22 @@
---
slug: /general/why-cpp
id: why-cpp
title: Why C++?
author: Benjamin Qi
order: 3
---
<module-excerpt>
A few reasons why choice of language matters significantly (outside of Bronze).
<!-- END DESCRIPTION -->
</module-excerpt>
## Time Limit
Although both Python and Java receive two times the C++ time limit in USACO, this is not the case for most other websites (ex. CodeForces). Even with the extended time limits, Python and Java sometimes have trouble passing.
- Rewriting the C++ solution for [USACO Silver Wormsort](http://www.usaco.org/index.php?page=viewproblem2&cpid=992) in Python receives TLE (Time Limit Exceeded) on 2/10 cases.
- Rewriting the C++ solution for [USACO Silver Wormsort](http://www.usaco.org/index.php?page=viewproblem2&cpid=992) in Python receives TLE (Time Limit Exceeded) on 2/10 cases. I'm not sure whether it is possible to pass this problem with Python.
<details>
<summary>Python3 8/10 Solution</summary>
<spoiler title="Python3 8/10 Solution">
```py
# 8/10 test cases ...
@ -90,13 +89,11 @@ Although both Python and Java receive two times the C++ time limit in USACO, thi
fout.write('\n')
```
</details>
</spoiler>
- A similar solution in Java requires almost 3s, which is fairly close to the time limit of 4s.
<details>
<summary>Java Solution</summary>
<spoiler title="Java Solution">
```java
import java.io.*; // from Nick Wu
@ -166,12 +163,11 @@ Although both Python and Java receive two times the C++ time limit in USACO, thi
}
```
</details>
</spoiler>
- A comparable C++ solution runs in less than 700ms.
<details>
<summary>C++ Solution</summary>
<spoiler title="C++ Solution">
```cpp
#include <bits/stdc++.h>
@ -227,10 +223,10 @@ Although both Python and Java receive two times the C++ time limit in USACO, thi
cout << minW;
}
```
</details>
</spoiler>
## Other
## Other Notes
- USACO problemsetters don't always test Java (and rarely Python) solutions when setting constraints.
- Python lacks a data structure that keeps its keys in sorted order (the equivalent of `set` in C++), which is required for some silver problems.
- Java lacks features such as `#define`, `typedef`, and `auto` that are present in C++ (which some contestants rely on extensively, see "macros").
- USACO problemsetters don't always test Java solutions (and rarely Python) when setting constraints.

View file

@ -1,11 +1,12 @@
---
slug: /bronze/overview
id: overview
title: "Bronze Overview"
author: Brian Dean
order: 1
---
<!-- END DESCRIPTION -->
<module-excerpt>
</module-excerpt>
Todo:
- Brian's advice for new bronze competitors

View file

@ -1,10 +0,0 @@
---
slug: /bronze/rectangle-geometry
title: "Rectangle Geometry"
author: Unknown
order: 2
---
See 7.1 of https://www.overleaf.com/project/5e73f65cde1d010001224d8a
usually just loop over 2D array

View file

@ -1,10 +0,0 @@
---
slug: /bronze/simulation
title: "Simulation"
author: Unknown
order: 7
---
See 5 of https://www.overleaf.com/project/5e73f65cde1d010001224d8a
<!-- END DESCRIPTION -->

View file

@ -1,10 +0,0 @@
---
slug: /bronze/complete-search
title: "Complete Search"
author: Unknown
order: 8
---
See 6 of https://www.overleaf.com/project/5e73f65cde1d010001224d8a
<!-- END DESCRIPTION -->

View file

@ -0,0 +1,138 @@
---
id: complete-search
title: "Complete Search"
author: Darren Yao
---
<module-excerpt>
In many problems (especially in Bronze), it's sufficient to check all possible cases in the solution space, whether it be all elements, all pairs of elements, or all subsets, or all permutations. Unsurprisingly, this is called **complete search** (or **brute force**), because it completely searches the entire solution space.
</module-excerpt>
## Example 1
### Statement
You are given $N$ $(3 \leq N \leq 5000)$ integer points on the coordinate plane. Find the square of the maximum Euclidean distance (aka length of the straight line) between any two of the points.
#### Input Format
The first line contains an integer $N$.
The second line contains $N$ integers, the $x$-coordinates of the points: $x_1, x_2, \dots, x_N$ ($-1000 \leq x_i \leq 1000$).
The third line contains $N$ integers, the $y$-coordinates of the points: $y_1, y_2, \dots, y_N$ ($-1000 \leq y_i \leq 1000$).
#### Output Format
Print one integer, the square of the maximum Euclidean distance between any two of the points.
### Solution
We can brute-force every pair of points and find the square of the distance between them, by squaring the formula for Euclidean distance: $\text{distance}^2 = (x_2-x_1)^2 + (y_2-y_1)^2$. Thus, we store the coordinates in arrays \mintinline{java}{X[]} and \mintinline{java}{Y[]}, such that \mintinline{java}{X[i]} and \mintinline{java}{Y[i]} are the $x$- and $y$-coordinates of the $i_{th}$ point, respectively. Then, we iterate through all possible pairs of points, using a variable max to store the maximum square of distance between any pair seen so far, and if the square of the distance between a pair is greater than our current maximum, we set our current maximum to it.
Java:
```java
int max = 0; // storing the current maximum
for(int i = 0; i < n; i++){ // for each first point
for(int j = i+1; j < n; j++){ // for each second point
int dx = x[i] - x[j];
int dy = y[i] - y[j];
max = Math.max(max, dx*dx + dy*dy);
// if the square of the distance between the two points is greater than
// our current maximum, then update the maximum
}
}
pw.println(max);
```
C++
```cpp
int high = 0; // storing the current maximum
for(int i = 0; i < n; i++){ // for each first point
for(int j = i+1; j < n; j++){ // for each second point
int dx = x[i] - x[j];
int dy = y[i] - y[j];
high = max(high, dx*dx + dy*dy);
// if the square of the distance between the two points is greater than
// our current maximum, then update the maximum
}
}
cout << high << endl;
```
A couple notes: first, since we're iterating through all pairs of points, we start the $j$ loop from $j = i+1$ so that point $i$ and point $j$ are never the same point. Furthermore, it makes it so that each pair is only counted once. In this problem, it doesn't matter whether we double-count pairs or whether we allow $i$ and $j$ to be the same point, but in other problems where we're counting something rather than looking at the maximum, it's important to be careful that we don't overcount. Secondly, the problem asks for the square of the maximum Euclidean distance between any two points. Some students may be tempted to maintain the maximum distance in a variable, and then square it at the end when outputting. However, the problem here is that while the square of the distance between two integer points is always an integer, the distance itself isn't guaranteed to be an integer. Thus, we'll end up shoving a non-integer value into an integer variable, which truncates the decimal part. Using a floating point variable isn't likely to work either, due to precision errors (use of floating point decimals should generally be avoided when possible).
(uh, have you verified this claim?)
## Generating Permutations
A **permutation** is a reordering of a list of elements. Some problems will ask for an ordering of elements that satisfies certain conditions. In these problems, if $N \leq 10$, we can probably iterate through all permutations and check each permutation for validity. For a list of $N$ elements, there are $N!$ ways to permute them, and generally we'll need to read through each permutation once to check its validity, for a time complexity of $O(N \cdot N!)$.
In Java, we'll have to implement this ourselves, which is called [Heap's Algorithm](https://en.wikipedia.org/wiki/Heap%27s_algorithm) (no relation to the heap data structure). What's going to be in the check function depends on the problem, but it should verify whether the current permutation satisfies the constraints given in the problem.
As an example, here are the permutations generated by Heap's Algorithm for \([1, 2, 3]\):
$$[1, 2, 3], [2, 1, 3], [3, 1, 2], [1, 3, 2], [2, 3, 1], [3, 2, 1]$$
Code for iterating over all permutations is as follows:
```java
// this method is called with k equal to the length of arr
static void generate(int[] arr, int k){
if(k == 1){
check(arr); // check the current permutation for validity
} else {
generate(arr, k-1);
for(int i = 0; i < k-1; i++){
if(k % 2 == 0){
swap(arr, i, k-1);
// swap indices i and k-1 of arr
} else {
swap(arr, 0, k-1);
// swap indices 0 and k-1 of arr
}
}
}
}
```
In C++, we can just use the `next_permutation()` function. To iterate through all permutations, place this inside a do-while loop.
```cpp
do {
check(v); // process or check the current permutation for validity
} while(next_permutation(v.begin(), v.end()));
```
## Problems
- USACO Bronze
- [Triangles](http://usaco.org/index.php?page=viewproblem2&cpid=1011)
- [Photoshoot](http://www.usaco.org/index.php?page=viewproblem2&cpid=988)
- Hint: Figure out what exactly you're complete searching
- [Cow Gymnastics](http://usaco.org/index.php?page=viewproblem2&cpid=963)
- Hint: Brute force over all possible pairs
- [Milk Pails](http://usaco.org/index.php?page=viewproblem2&cpid=615)
- [Lifeguards](http://usaco.org/index.php?page=viewproblem2&cpid=784)
- Hint: Try removing each lifeguard one at a time.
- [Where Am I?](http://usaco.org/index.php?page=viewproblem2&cpid=964)
- Hint: Brute force over all possible substrings.
- (Permutations) [Livestock Lineup](http://usaco.org/index.php?page=viewproblem2&cpid=965)
- [Field Reduction](http://www.usaco.org/index.php?page=viewproblem2&cpid=641)
- Hint: For this problem, you can't do a full complete search; you have to do a reduced search)
- [Back and Forth](http://www.usaco.org/index.php?page=viewproblem2&cpid=857)
- Somewhat harder
- USACO Silver
- [Bovine Genomics](http://usaco.org/index.php?page=viewproblem2&cpid=739)
- [Field Reduction](http://usaco.org/index.php?page=viewproblem2&cpid=642)
- CSES
- (Permutations) [Chessboard and Queens](https://cses.fi/problemset/task/1624)

View file

@ -0,0 +1,145 @@
---
id: containers
title: Built-In C++ Containers
author: Darren Yao
---
<module-excerpt>
Introduces C++ [containers](http://www.cplusplus.com/reference/stl/) that are frequently used in competitive programming.
</module-excerpt>
A **data structure** determines how data is stored (is it sorted? indexed? what operations does it support?). Each data structure supports some operations efficiently, while other operations are either inefficient or not supported at all.
# Containers
The C++ standard library data structures are designed to store any type of data. We put the desired data type within the `<>` brackets when declaring the data structure, as follows:
```cpp
vector<string> v;
```
This creates a `vector` structure that only stores objects of type `string`.
For our examples below, we will primarily use the `int` data type, but note that you can use any data type including `string` and user-defined structures.
Essentially every standard library data structure supports the `size()` method, which returns the number of elements in the data structure, and the `empty()` method, which returns `true` if the data structure is empty, and `false` otherwise.
## Dynamic Arrays
You're probably already familiar with regular (static) arrays. Now, there are also dynamic arrays (`vector` in C++) that support all the functions that a normal array does, and can resize itself to accommodate more elements. In a dynamic array, we can also add and delete elements at the end in $O(1)$ time.
For example, the following code creates a dynamic array and adds the numbers $1$ through $10$ to it:
```cpp
vector<int> v;
for(int i = 1; i <= 10; i++){
v.push_back(i);
}
```
When declaring a dynamic array we can give it an initial size, so it doesn't resize itself as we add elements to it. The following code initializes a `vector` with initial size $30$:
```cpp
vector<int> v(30);
```
However, we need to be careful that we only add elements to the end of the `vector`; insertion and deletion in the middle of the `vector` is $O(n)$.
```cpp
vector<int> v;
v.push_back(2); // [2]
v.push_back(3); // [2, 3]
v.push_back(7); // [2, 3, 7]
v.push_back(5); // [2, 3, 7, 5]
v[1] = 4; // sets element at index 1 to 4 -> [2, 4, 7, 5]
v.erase(v.begin() + 1); // removes element at index 1 -> [2, 7, 5]
// this remove method is O(n); to be avoided
v.push_back(8); // [2, 7, 5, 8]
v.erase(v.end()-1); // [2, 7, 5]
// here, we remove the element from the end of the list; this is O(1).
v.push_back(4); // [2, 7, 5, 4]
v.push_back(4); // [2, 7, 5, 4, 4]
v.push_back(9); // [2, 7, 5, 4, 4, 9]
cout << v[2]; // 5
v.erase(v.begin(), v.begin()+3); // [4, 4, 9]
// this erases the first three elements; O(n)
```
To iterate through a static or dynamic array, we can use either the regular for loop or the for-each loop.
```cpp
vector<int> v;
v.push_back(1); v.push_back(7); v.push_back(4); v.push_back(5); v.push_back(2);
int arr[] = {1, 7, 4, 5, 2};
for(int i = 0; i < v.size(); i++){
cout << v[i] << " ";
}
cout << endl;
for(int element : arr){
cout << element << " ";
}
cout << endl;
```
In order to sort a dynamic array, use `sort(v.begin(), v.end())` (or `sort(begin(v),end(v))`), whereas static arrays require `sort(arr, arr + N)` where $N$ is the number of elements to be sorted. The default sort function sorts the array in ascending order.
In array-based contest problems, we'll use one-, two-, and three-dimensional static arrays most of the time. However, we can also have static arrays of dynamic arrays, dynamic arrays of static arrays, and so on. Usually, the choice between a static array and a dynamic array is just personal preference.
## Iterators
An **iterator** allows you to traverse a container by pointing to an object within the container (although they are **not** the same thing as pointers). For example, `vector.begin()` returns an iterator pointing to the first element of the vector. Apart from the standard way of traversing a vector (by treating it as an array), you can also use iterators:
```cpp
for (vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
cout << *it; //prints the values in the vector using the pointer
}
```
C++11 and later versions can automatically infer the type of an object if you use the keyword `auto`. This means that you can replace `vector<int>::iterator` with `auto` or `int` with `auto` in the for-each loop.
```cpp
for(auto element : v) {
cout << element; //prints the values in the vector
}
```
## Stacks and the Various Types of Queues
### [Stacks](http://www.cplusplus.com/reference/stack/stack/)
A stack is a **Last In First Out** (LIFO) data structure that supports three operations, all in $O(1)$ time:
- `push`: adds an element to the top of the stack
- `pop`: removes an element from the top of the stack
- `top`: retrieves the element at the top without removing it
Think of it like a real-world stack of papers (or cards).
```cpp
stack<int> s;
s.push(1); // [1]
s.push(13); // [1, 13]
s.push(7); // [1, 13, 7]
cout << s.top() << endl; // 7
s.pop(); // [1, 13]
cout << s.size() << endl; // 2
```
### [Queues](http://www.cplusplus.com/reference/queue/queue/ )
A queue is a First In First Out (FIFO) data structure that supports three operations, all in $O(1)$ time.
- `push`: insertion at the back of the queue
- `pop`, deletion from the front of the queue
- `front`: which retrieves the element at the front without removing it.
```cpp
queue<int> q;
q.push(1); // [1]
q.push(3); // [3, 1]
q.push(4); // [4, 3, 1]
q.pop(); // [4, 3]
cout << q.front() << endl; // 3
```

View file

@ -1,41 +1,37 @@
---
slug: /bronze/ds
id: ds
title: Data Structures
author: Nathan Wang, ?
author: Nathan Wang, Darren Yao, Benjamin Qi
order: 5
---
<module-excerpt>
Problems and additional resources regarding built-in data structures.
<!-- END DESCRIPTION -->
(clean this up)
</module-excerpt>
## Problems
(actually go through these ...)
**CSES:**
**Stack:**:
Do roughly the first half of the Sorting and Searching section in the [CSES Problem Set](https://cses.fi/problemset/)
(actually go through these and check ...)
**Stack:**
- UVa 00514 - Rails
- UVa 00732 - Anagram by Stack
- UVa 01062 - Containers
**Queue/Deque:**:
**Queue/Deque:**
- UVa 10172 - The Lonesome Cargo
- UVa 10901 - Ferry Loading III
- UVa 11034 - Ferry Loading IV
**Ordered Maps:**:
- UVa 10226 - Hardwood Species
- UVa 11286 - Conformity
- UVa 11572 - Unique Snowflakes
**Set/Multiset:**
- UVa 00978 - Lemmings Battle
- UVa 11136 - Hoax or what
- UVa 11849 - CD
**General:**
- [Beautiful Triplets](https://www.hackerearth.com/practice/algorithms/greedy/basics-of-greedy-algorithms/practice-problems/algorithm/mancunian-and-beautiful-triplets-30968257/) [](54)

View file

@ -0,0 +1,45 @@
---
id: intro-graphs
title: Introduction to Graphs
author: Darren Yao, Benjamin Qi
---
<module-excerpt>
**Graph theory** is one of the most important topics at the Silver level and above, although some basic problems occasionally appear in Bronze.
</module-excerpt>
Graphs can be used to represent many things, from images to wireless signals, but one of the simplest analogies is to a map. Consider a map with several cities and highways connecting the cities. Some problems relating to graphsare:
- If we have a map with some cities and roads, what's the shortest distance I have to travel to get from point A to point B?
- Consider a map of cities and roads. Is city A connected to city B? Consider a region to be a group of cities such that each city in the group can reach any other city in said group, but no other cities. How many regions are in this map, and which cities are in which region?
Both of these will be covered in Silver. For now, it suffices to learn how graphs are represented.
## Tutorial
- Recommended
- CPH 11
- Intro to USACO 10.1 - 10.3
- [CSAcademy Graph Intro](https://csacademy.com/lesson/introduction_to_graphs)
- [CSAcademy Graph Representations](https://csacademy.com/lesson/graph_representation)
- Usually, adjacency lists are used.
- Other
- [Topcoder Graphs Pt 1](https://www.topcoder.com/community/data-science/data-science-tutorials/introduction-to-graphs-and-their-data-structures-section-1/)
## Trees?
## USACO Bronze Problems
(add some more)
- Tree
- [Factory](http://usaco.org/index.php?page=viewproblem2&cpid=940)
- [Family Tree](http://usaco.org/index.php?page=viewproblem2&cpid=833)
- [Grass Planting (Silver)](http://usaco.org/index.php?page=viewproblem2&cpid=894)
- Permutation
- [Swapity Swap](http://usaco.org/index.php?page=viewproblem2&cpid=1013)
- General Graph
- [The Great Revegetation](http://usaco.org/index.php?page=viewproblem2&cpid=916)

View file

@ -1,13 +1,14 @@
---
slug: /bronze/collections
id: collections
title: Built-In Java Collections
author: Darren Yao
order: 3
---
Introduces the data structures in the Java standard library that are frequently used in competitive programming.
<module-excerpt>
<!-- END DESCRIPTION -->
Introduces data structures from Java [Collections](https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html) that are frequently used in competitive programming.
</module-excerpt>
A **data structure** determines how data is stored (is it sorted? indexed? what operations does it support?). Each data structure supports some operations efficiently, while other operations are either inefficient or not supported at all.
@ -165,7 +166,7 @@ for(int element : set){
### Ordered Sets
The second type of set data structure is the ordered or sorted set. Insertions, deletions, and searches on the ordered set require O(\log n) time, based on the number of elements in the set. As well as those supported by the unordered set, the ordered set also allows four additional operations: `first`, which returns the lowest element in the set, `last`, which returns the highest element in the set, `lower`, which returns the greatest element strictly less than some element, and `higher`, which returns the least element strictly greater than it.
The second type of set data structure is the ordered or sorted set. Insertions, deletions, and searches on the ordered set require $O(\log n)$ time, based on the number of elements in the set. As well as those supported by the unordered set, the ordered set also allows four additional operations: `first`, which returns the lowest element in the set, `last`, which returns the highest element in the set, `lower`, which returns the greatest element strictly less than some element, and `higher`, which returns the least element strictly greater than it.
```java
TreeSet<Integer> set = new TreeSet<Integer>();
@ -218,7 +219,7 @@ System.out.println(map.firstKey()); // 3
System.out.println(map.firstEntry()); // (3, 5)
System.out.println(map.lastEntry()); // (11, 4)
System.out.println(map.higherEntry(4)); // (10, 491)
map.remove(11); // [(3, 5); (11, 4)]
map.remove(11); // [(3, 5); (10, 491)]
System.out.println(map.lowerKey(4)); // 3
System.out.println(map.lowerKey(3)); // ERROR
```
@ -252,4 +253,4 @@ static void remove(int x){
}
```
The first, last, higher, and lower operations still function as intended; just use `firstKey`, `lastKey`, `higherKey`, and `lowerKey` respectively.
The first, last, higher, and lower operations still function as intended; just use `firstKey`, `lastKey`, `higherKey`, and `lowerKey` respectively.

View file

@ -1,15 +1,17 @@
---
slug: /bronze/pairs
id: pairs
title: Pairs & Tuples
author: Aaron Chew, Benjamin Qi, Nathan Wang
author: Aaron Chew, Benjamin Qi, Nathan Wang, Darren Yao
order: 6
---
<module-excerpt>
A **pair** is a structure that holds two values, not necessarily of the same type.
(tuples?)
<!-- END DESCRIPTION -->
</module-excerpt>
Of course, we can hold more than two values with something like ```pair<int,pair<int,int>>```.
@ -31,8 +33,6 @@ using namespace std;
int main() {
pair<string, int> myPair = make_pair("Testing", 123);
cout << myPair.first << " " << myPair.second << endl; // Testing 123
vector<pair<int,int>> v = {{2,4},{1,3},{3,4},{3,1}};
sort(begin(v),end(v)); // {(1, 3), (2, 4), (3, 1), (3, 4)}
}
/* Output
@ -64,4 +64,6 @@ class pair implements Comparable <pair>{
```
If you have an array ```pair[]arr=new pair[100]```, make sure each element of this array is not null. You can call ```Arrays.sort(arr);``` on this array and it will sort it by all the ```first``` of the array and if there is a tie in ```first``` it will sort by ```second```.
If you want to sort by 3 or more elements, it's a simple change. Just add a new variable in ```pair``` and make sure the comparable compares in the right order you want.
You can also use an `int[]` as a pair, or if you're using a pair of two different types, you can use `Object[]`.
If you want to sort by 3 or more elements, it's a simple change. Just add a new variable in ```pair``` and make sure the comparable compares in the right order you want.

View file

@ -0,0 +1,135 @@
---
id: rect-geo
title: "Rectangle Geometry"
author: Darren Yao, Michael Cao
---
<module-excerpt>
"Geometry" problems on USACO Bronze are usually quite simple and limited to intersections and unions of squares or rectangles.
</module-excerpt>
- Some only include two or three squares or rectangles, in which case you can simply draw out cases on paper. This should logically lead to a solution.
- Also, the coordinates typically only go up to $1000$, so a program that performs $\approx 1000^2$ operations (ex. with a nested loop) should pass.
## Rectangle Class (Java)
A useful class in `Java` for dealing with rectangle geometry problems is the built-in [`Rectangle`](https://docs.oracle.com/javase/8/docs/api/java/awt/Rectangle.html) class. To create a new rectangle, use the following constructor:
```java
//creates a rectangle with upper-left corner at (x,y) with a specified width and height
Rectangle newRect = new Rectangle(x, y, width, height);
```
The `Rectangle` class supports numerous useful methods.
`firstRect.intersects(secondRect)` checks if two rectangles intersect.
`firstRect.union(secondRect)` returns a rectangle representing the union of two rectangles.
`firstRect.contains(x, y)` checks whether the integer point (x,y) exists in firstRect.
`firstRect.intersection(secondRect)` returns a rectangle representing the intersection of two rectangles.
This class can often lessen the implementation needed in a lot of bronze problems and CodeForces problems.
For example, here is a nice implementation of the problem [Blocked Billboard](http://usaco.org/index.php?page=viewproblem2&cpid=759) ([editorial](http://www.usaco.org/current/data/sol_billboard_bronze_dec17.html)).
<spoiler title="Java Solution">
```java
import java.awt.Rectangle; //needed to use Rectangle class
import java.io.*;
import java.util.*;
public class blockedBillboard{
public static void main(String[] args) throws IOException{
Scanner sc = new Scanner(new File("billboard.in"));
PrintWriter pw = new PrintWriter(new FileWriter("billboard.out"));
int x1, y1, x2, y2;
//the top left point is (0,0), so you need to do -y2
x1 = sc.nextInt(); y1 = sc.nextInt(); x2 = sc.nextInt(); y2 = sc.nextInt();
Rectangle firstRect = new Rectangle(x1, -y2, x2-x1, y2-y1);
x1 = sc.nextInt(); y1 = sc.nextInt(); x2 = sc.nextInt(); y2 = sc.nextInt();
Rectangle secondRect = new Rectangle(x1, -y2, x2-x1, y2-y1);
x1 = sc.nextInt(); y1 = sc.nextInt(); x2 = sc.nextInt(); y2 = sc.nextInt();
Rectangle truck = new Rectangle(x1, -y2, x2-x1, y2-y1);
long firstIntersect = getArea(firstRect.intersection(truck));
long secondIntersect = getArea(secondRect.intersection(truck));
pw.println(getArea(firstRect) + getArea(secondRect)
- firstIntersect - secondIntersect);
pw.close();
}
public static long getArea(Rectangle r){
if(r.getWidth() <= 0 || r.getHeight() <= 0){
return 0;
}
return (long)r.getHeight() * (long)r.getWidth();
}
}
```
</spoiler>
## Rectangle Class (C++)
Unfortunately, C++ doesn't have a built in rectangle class, so you need to write the functions yourself. Here is the solution to Blocked Billboard written in C++ (thanks, Brian Dean!).
<spoiler title="C++ Solution">
```cpp
#include <iostream>
#include <fstream>
using namespace std;
struct Rect{
int x1, y1, x2, y2;
};
int area(Rect r){
return (r.y2 - r.y1) * (r.x2 - r.x1);
}
int intersect(Rect p, Rect q){
int xOverlap = max(0, min(p.x2, q.x2) - max(p.x1, q.x1));
int yOverlap = max(0, min(p.y2, q.y2) - max(p.y1, q.y1));
return xOverlap * yOverlap;
}
int main(){
ifstream cin ("billboard.in");
ofstream cout ("billboard.out");
Rect a, b, t; // billboards a, b, and the truck
cin >> a.x1 >> a.y1 >> a.x2 >> a.y2;
cin >> b.x1 >> b.y1 >> b.x2 >> b.y2;
cin >> t.x1 >> t.y1 >> t.x2 >> t.y2;
cout << area(a) + area(b) - intersect(a, t) - intersect(b, t);
}
```
</spoiler>
## Problems
- USACO Bronze
- [Fence Painting](http://usaco.org/index.php?page=viewproblem2&cpid=567)
- 1D geometry!!
- [Square Pasture](http://usaco.org/index.php?page=viewproblem2&cpid=663)
- [Blocked Billboard](http://usaco.org/index.php?page=viewproblem2&cpid=759)
- Rectangles
- [Blocked Billboard II](http://usaco.org/index.php?page=viewproblem2&cpid=783)
- Also rectangles
- Other
- [CF 587 (Div. 3) C: White Sheet](https://codeforces.com/contest/1216/problem/C)
- See this code (TODO; codeforces is down) for a nice implementation using the Java Rectangle class.

View file

@ -0,0 +1,130 @@
---
id: simulation
title: "Simulation"
author: Darren Yao
---
<module-excerpt>
In many problems, we can **simulate** what we're told to do by the problem statement.
</module-excerpt>
Since there's no formal algorithm involved, the intent of the problem is to assess competence with one's programming language of choice and knowledge of built-in data structures. At least in USACO Bronze, when a problem statement says to find the end result of some process, or to find when something occurs, it's usually sufficient to simulate the process naively.
## Example 1
### Statement
Alice and Bob are standing on a 2D plane. Alice starts at the point $(0, 0)$, and Bob starts at the point $(R, S)$ ($1 \leq R, S \leq 1000$). Every second, Alice moves $M$ units to the right, and $N$ units up. Every second, Bob moves $P$ units to the left, and $Q$ units down. ($1 \leq M, N, P, Q \leq 10$). Determine if Alice and Bob will ever meet (be at the same point at the same time), and if so, when.
#### Input Format
The first line of the input contains $R$ and $S$.
The second line of the input contains $M$, $N$, $P$, and $Q$.
#### Output Format
Please output a single integer containing the number of seconds after the start at which Alice and Bob meet. If they never meet, please output $-1$.
### Solution
We can simulate the process. After inputting the values of $R$, $S$, $M$, $N$, $P$, and $Q$, we can keep track of Alice's and Bob's $x$- and $y$-coordinates. To start, we initialize variables for their respective positions. Alice's coordinates are initially \((0, 0)\), and Bob's coordinates are $(R, S)$ respectively. Every second, we increase Alice's $x$-coordinate by $M$ and her $y$-coordinate by $N$, and decrease Bob's $x$-coordinate by $P$ and his $y$-coordinate by $Q$.
Now, when do we stop? First, if Alice and Bob ever have the same coordinates, then we are done. Also, since Alice strictly moves up and to the right and Bob strictly moves down and to the left, if Alice's $x$- or $y$-coordinates are ever greater than Bob's, then it is impossible for them to meet.
Example Java code is displayed below. Here, as in other examples, input processing will be omitted).
```java
int ax = 0; int ay = 0; // alice's x and y coordinates
int bx = r; int by = s; // bob's x and y coordinates
int t = 0; // keep track of the current time
while(ax < bx && ay < by){
// every second, update alice's and bob's coordinates and the time
ax += m; ay += n;
bx -= p; by -= q;
t++;
}
if(ax == bx && ay == by){ // if they are in the same location
out.println(t); // they meet at time t
} else {
out.println(-1); // they never meet
}
out.close(); // flush the output
```
For C++, replaces lines such as `out.println(t)` with `cout << t << endl`.
## Example 2
### Statement
There are $N$ buckets ($5 \leq N \leq 10^5$), each with a certain capacity $C_i$ ($1 \leq C_i \leq 100$). One day, after a rainstorm, each bucket is filled with $A_i$ units of water ($1\leq A_i \leq C_i$). Charlie then performs the following process: he pours bucket 1 into bucket 2, then bucket 2 into bucket 3, and so on, up until pouring bucket $N-1$ into bucket $N$. When Charlie pours bucket $B$ into bucket $B+1$, he pours as much as possible until bucket $B$ is empty or bucket $B+1$ is full. Find out how much water is in each bucket once Charlie is done pouring.
#### Input Format
The first line of the input contains $N$.
The second line of the input contains the capacities of the buckets, $C_1, C_2, \dots, C_N$.
The third line of the input contains the amount of water in each bucket $A_1, A_2, \dots, A_N$.
#### Output Format
Please print one line of output, containing $N$ space-separated integers: the final amount of water in each bucket once Charlie is done pouring.
### Solution
Once again, we can simulate the process of pouring one bucket into the next. The amount of milk poured from bucket $B$ to bucket $B+1$ is the smaller of the amount of water in bucket $B$ (after all previous operations have been completed) and the remaining space in bucket $B+1$, which is $C_{B+1} - A_{B+1}$. We can just handle all of these operations in order, using an array C to store the maximum capacities of each bucket, and an array A to store the current water level in each bucket, which we update during the process. Example code is below (note that arrays are zero-indexed, so the indices of our buckets go from $0$ to $N-1$ rather than from $1$ to $N$).
Java:
```java
for(int i = 0; i < n-1; i++){
int amt = Math.min(A[i], C[i+1]-A[i+1]);
// the amount of water to be poured is the lesser of
// the amount of water in the current bucket and
// the amount of additional water that the next bucket can hold
A[i] -= amt; // remove the amount from the current bucket
A[i+1] += amt; // add it to the next bucket
}
for(int i = 0; i < n; i++){
pw.print(A[i] + " ");
// print the amount of water in each bucket at the end
}
pw.println(); // print newline
pw.close(); // flush the output
```
C++:
```cpp
for(int i = 0; i < n-1; i++){
int amt = min(A[i], C[i+1]-A[i+1]);
// the amount of water to be poured is the lesser of
// the amount of water in the current bucket and
// the amount of additional water that the next bucket can hold
A[i] -= amt; // remove the amount from the current bucket
A[i+1] += amt; // add it to the next bucket
}
for(int i = 0; i < n; i++){
cout << A[i] << " ";
// print the amount of water in each bucket at the end
}
cout << endl;
```
## USACO Bronze Problems
- [Mixing Milk](http://www.usaco.org/index.php?page=viewproblem2&cpid=855)
- [Milk Measurement](http://www.usaco.org/index.php?page=viewproblem2&cpid=761)
- [The Lost Cow](http://www.usaco.org/index.php?page=viewproblem2&cpid=735)
- [Why Did the Cow Cross the Road III](http://www.usaco.org/index.php?page=viewproblem2&cpid=713)
- [Mowing the Field](http://www.usaco.org/index.php?page=viewproblem2&cpid=593)
- [The Bovine Shuffle](http://usaco.org/index.php?page=viewproblem2&cpid=760)
- [Circular Barn](http://usaco.org/index.php?page=viewproblem2&cpid=616)

View file

@ -1,19 +1,20 @@
---
slug: /silver/complexity
id: time-comp
title: "Time Complexity"
author: Darren Yao, Benjamin Qi
order: 1
---
<module-excerpt>
In programming contests, there is a strict limit on program runtime. This means that in order to pass, your program needs to finish running within a certain timeframe.
<!-- END DESCRIPTION -->
</module-excerpt>
For USACO, this limit is $4$ seconds for Java submissions. A conservative estimate for the number of operations the grading server can handle per second is $10^8$ (but could be closer to $5 \cdot 10^8$ given good constant factors).
## [Big O Notation](https://en.wikipedia.org/wiki/Big_O_notation) and Complexity Calculations
## Complexity Calculations
We want a method of how many operations it takes to run each algorithm, in terms of the input size $n$. Fortunately, this can be done relatively easily using **Big O notation**, which expresses worst-case complexity as a function of $n$ as $n$ gets arbitrarily large. Complexity is an upper bound for the number of steps an algorithm requires as a function of the input size. In Big O notation, we denote the complexity of a function as $O(f(n))$, where $f(n)$ is a function without constant factors or lower-order terms. We'll see some examples of how this works, as follows.
We want a method of how many operations it takes to run each algorithm, in terms of the input size $n$. Fortunately, this can be done relatively easily using [Big O Notation](https://en.wikipedia.org/wiki/Big_O_notation), which expresses worst-case complexity as a function of $n$ as $n$ gets arbitrarily large. Complexity is an upper bound for the number of steps an algorithm requires as a function of the input size. In Big O notation, we denote the complexity of a function as $O(f(n))$, where $f(n)$ is a function without constant factors or lower-order terms. We'll see some examples of how this works, as follows.
The following code is $O(1)$, because it executes a constant number of operations.
@ -142,3 +143,6 @@ Here are conservative upper bounds on the value of $n$ for each time complexity.
## Other Resources
- CPH 2

View file

@ -1,16 +1,17 @@
---
slug: /silver/two-pointers
id: 2P
title: "Two Pointers"
author: Darren Yao
order: 5
prerequisites:
-
- Silver - Sorting
---
<module-excerpt>
**Two pointers** refers to iterating two monotonic pointers across an array to search for a pair of indices satisfying some condition in $O(n)$ time.
<!-- END DESCRIPTION -->
</module-excerpt>
## Tutorials

View file

@ -1,33 +0,0 @@
---
slug: /silver/greedy
title: "Greedy Algorithms"
author: Darren Yao
order: 2
---
**Greedy algorithms** are algorithms that select the optimal choice at each step instead of looking at the solution space as a whole. This reduces the problem to a smaller problem at each step.
<!-- END DESCRIPTION -->
# Tutorials
- Intro to USACO, Chapter 9
- Interval Cover
- CPH 6
- [CPC.5](https://github.com/SuprDewd/T-414-AFLV/tree/master/05_greedy_algorithms)
# Problems
USACO
- [USACO Why Did the Cow Cross the Road](http://www.usaco.org/index.php?page=viewproblem2&cpid=714)
- [USACO Rest Stops](http://www.usaco.org/index.php?page=viewproblem2&cpid=810)
- [USACO High Card Wins](http://usaco.org/index.php?page=viewproblem2&cpid=571)
Misc
- [Sure Bet](https://csacademy.com/contest/archive/task/sure-bet/)
- [Did you Mean...](http://codeforces.com/contest/860/problem/A)
- [Permutation](http://codeforces.com/problemset/problem/864/D)
- [Bus](http://codeforces.com/problemset/problem/864/C)
- [Kayaking](http://codeforces.com/problemset/problem/863/B)

View file

@ -1,26 +0,0 @@
---
slug: /silver/sorting
title: "Sorting"
author: Unknown
order: 3
prerequisites:
-
- Bronze - Data Structures
---
<!-- END DESCRIPTION -->
- Custom Comparators (prerequisite for basically all silver topics in Java)
- CPH 3
- std::sort / Collections.sort
- coord compress
See 8 of https://www.overleaf.com/project/5e73f65cde1d010001224d8a
See 12 of https://www.overleaf.com/project/5e73f65cde1d010001224d8a
- [Breaking Java Arrays.sort()](https://codeforces.com/blog/entry/4827)
- no longer works, see [this one](https://codeforces.com/contest/1324/submission/73058869) instead
custom comparators

View file

@ -1,75 +0,0 @@
---
slug: /silver/binary-search
title: "Binary Search"
author: Nathan Chen
order: 4
prerequisites:
-
- Silver - Sorting
---
[Binary search](https://en.wikipedia.org/wiki/Binary_search_algorithm) can be used on monotonic functions for a logarithmic runtime.
<!-- END DESCRIPTION -->
## Basic Application
Here is a very basic form of binary search:
> Find an element in a sorted array of size $N$ in $O(\log N)$ time.
Other variations are similar, such as the following:
> Given $K$, find the largest element less than $K$ in a sorted array.
## Tutorial
- CSES 3.3
- [Topcoder Binary Search](https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/)
- [CSAcademy Binary Search](https://csacademy.com/lesson/binary_search)
- [KA Binary Search](https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/binary-search)
- [GeeksForGeeks](https://www.geeksforgeeks.org/binary-search/)
### Library Functions to do Binary Search
#### Java
- [Arrays.binarySearch](https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html)
- [Collections.binarySearch](https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html)
#### C++
- [lower_bound](http://www.cplusplus.com/reference/algorithm/lower_bound/)
- [upper_bound](http://www.cplusplus.com/reference/algorithm/upper_bound/)
### Problems
- [USACO Silver Counting Haybales](http://www.usaco.org/index.php?page=viewproblem2&cpid=666)
## Binary Searching on the Answer
Oftentimes used when you need to find the minimum or maximum of some quantity such that it satisfies some property.
### Tutorial
- Intro to USACO 12.1
### Problems
- USACO
- [USACO Silver - Cow Dance](http://www.usaco.org/index.php?page=viewproblem2&cpid=690)
- binary search on $K$ and simulate
- [USACO Silver - Convention](http://www.usaco.org/index.php?page=viewproblem2&cpid=858)
- determine whether $M$ buses suffice if every cow waits at most $T$ minutes
- use a greedy strategy (applies to next two problems as well)
- [USACO Silver - Angry Cows](http://usaco.org/index.php?page=viewproblem2&cpid=594)
- check in $O(N)$ how many haybales you can destroy with fixed radius $R$
- [USACO Silver - Social Distancing](http://www.usaco.org/index.php?page=viewproblem2&cpid=1038)
- check in $O(N+M)$ how many cows you can place with distance $D$
- [USACO Silver - Loan Repayment](http://www.usaco.org/index.php?page=viewproblem2&cpid=991)
- requires some rather tricky analysis to speed up naive $O(N\log N)$ solution
- CF
- [The Meeting Place Cannot Be Changed](http://codeforces.com/contest/782/problem/B) [](48)
- [Preparing for Merge Sort](http://codeforces.com/contest/847/problem/B) [](53)
- [Level Generation](http://codeforces.com/problemset/problem/818/F) [](54)
- [Packmen](http://codeforces.com/contest/847/problem/E) [](57)
- [Office Keys](http://codeforces.com/problemset/problem/830/A) [](60)

View file

@ -1,92 +0,0 @@
---
slug: /silver/prefix-sums
title: "Prefix Sums"
author: Eric Wei
order: 6
---
> Given an array $A_1,A_2,\ldots,A_N$, answer $Q$ queries of the following form: compute $A_L+A_{L+1}+\cdots+A_R$.
<!-- END DESCRIPTION -->
## Standard
- [CSES Range Sum Queries I](https://cses.fi/problemset/task/1646)
- [LeetCode Find Pivot Index](https://leetcode.com/problems/find-pivot-index/)
## Tutorials
This technique is also known as *cumulative sum* or *partial sums*.
- Intro to USACO 11
- CPH 9.1
## USACO Silver Problems
These problems are relatively straightforward.
- [USACO Breed Counting](http://www.usaco.org/index.php?page=viewproblem2&cpid=572)
- [USACO Subsequences Summing to Seven](http://www.usaco.org/index.php?page=viewproblem2&cpid=595)
Now we'll look at some extensions.
## Max Subarray Sum
- [Maximum Subarray Sum](https://cses.fi/problemset/task/1643)
(Note: This problem has a solution known as Kadane's Algorithm. Please *don't* use that solution; try to solve it with prefix sums.)
<details>
<summary>Why are the two methods equivalent?</summary>
Consider the desired maximum subarray. As you go along from left to right, the prefix sum solution will mark the start of that subarray as the "current minimum prefix sum". Kadane's Algorithm, on the other hand, will set the current value to 0 at that point. As both solutions iterate through the array, they eventually find the right side of the maximum sum, and they find the answer to the problem at that location. In essence, Kadane's Algorithm stores the maximum sum of a subarray that ends at the current location (which is what the prefix sum solution calculates on each iteration), but it calculates this value greedily instead.
</details>
Extension:
- [CSES Maximum Subarray Sum II](https://cses.fi/problemset/task/1644)
## Difference Array
**Task:** Given an array of size $N$, do the following operation $Q$ times: add $X$ to the values between $i$ and $j$. Afterwards, print the final array.
**Solution:** Consider the array formed by $a_i-a_{i-1}$. When processing a range addition, only two values in this difference array change! At the end, we can recover the original array using prefix sums. (The math is left as an exercise to the reader.)
- [USACO Haybale Stacking](http://www.usaco.org/index.php?page=viewproblem2&cpid=104)
## 2D Prefix Sums
Given a 2-dimensional array of size $N\cdot M$, answer $Q$ queries of the following form: Find the sum of all elements within the rectangle of indices $(x1,y1)$ to $(x2,y2)$.
- [CSES Forest Queries](https://cses.fi/problemset/task/1652)
- [USACO Painting the Barn (Silver)](http://www.usaco.org/index.php?page=viewproblem2&cpid=919)
- [USACO Painting the Barn (Gold)](http://www.usaco.org/index.php?page=viewproblem2&cpid=923)
- combine with max subarray sum!
## Prefix Minimum, XOR, etc.
Similar to prefix sums, you can also take prefix minimum or maximum; but *you cannot* answer min queries over an arbitrary range with prefix minimum. (This is because minimum doesn't have an inverse operation, the way subtraction is to addition.)
On the other hand, XOR is its own inverse operation, meaning that the XOR of any number with itself is zero.
- [USACO My Cow Ate My Homework](http://usaco.org/index.php?page=viewproblem2&cpid=762)
- [CSES Range XOR Queries](https://cses.fi/problemset/task/1650)
## More Complex Applications
Instead of storing just the values themselves, you can also take a prefix sum over $i\cdot a_i$, or $10^i \cdot a_i$, for instance. Some math is usually helpful for these problems; don't be afraid to get dirty with algebra!
For instance, let's see how to quickly answer the following type of query:
Find $1\cdot a_l+2\cdot a_{l+1}+3\cdot a_{l+2}+\cdots+(r-l+1)\cdot a_{r}$.
First, define the following: \
$ps[i] = a_1+a_2+a_3+a_4+\cdots+a_i \\ ips[i] = 1\cdot a_1+2\cdot a_2+\cdots+i\cdot a_i$
Then, we have: \
$l\cdot a_l + (l+1) \cdot a_{l+1} + \cdots + r \cdot a_r = ips[r]-ips[l-1] (l-1) \cdot a_l + (l-1) \cdot a_{l+1} + \cdot + (l-1) \cdot a_r = (l-1)(ps[r]-ps[l-1])$
And so, \
$1\cdot a_l + 2 \cdot a_{l+1} + \cdots + (r-l+1) \cdot a_r = ips[r]-ips[l-1]-(l-1)(ps[r]-ps[l-1])$
Which is what we were looking for!
- [AtCoder Multiple of 2019](https://atcoder.jp/contests/abc164/tasks/abc164_d)
- [Google Kick Start Candies](https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ff43/0000000000337b4d) (**only** Test Set 1.)

View file

@ -1,13 +0,0 @@
---
slug: /silver/data-structures
title: "Data Structures"
author: Unknown
order: 7
prerequisites:
-
- Bronze - Data Structures
---
More practice with data structures introduced in bronze.
<!-- END DESCRIPTION -->

View file

@ -0,0 +1,156 @@
---
id: binary-search
title: "Binary Search on the Answer"
author: Darren Yao
prerequisites:
-
- Silver - Introduction to Sorting
---
<module-excerpt>
You should already be familiar with the concept of **binary searching** for a number in a sorted array. However, binary search can be extended to binary searching on the answer itself.
</module-excerpt>
When we binary search on the answer, we start with a search space of size $N$ which we know the answer lies in. Then, each iteration of the binary search cuts the search space in half, so the algorithm tests $O(\log N)$ values. This is efficient and much better than testing each possible value in the search space.
Let's say we have a function `check(x)` that returns true if the answer of $x$ is possible, and false otherwise. Usually, in such problems, we'll want to find the maximum or minimum value of $x$ such that `check(x)` is true. Similarly to how binary search on an array only works on a sorted array, binary search on the answer only works if the answer function is [monotonic](https://en.wikipedia.org/wiki/Monotonic_function), meaning that it is always non-decreasing or always non-increasing.
In particular, if we want to find the maximum `x` such that `check(x)` is true, then we can binary search if `check(x)` satisfies both of the following conditions:
- If `check(x)` is `true`, then `check(y)` is true for all $y \leq x$.
- If `check(x)` is `false`, then `check(y)` is false for all $y \geq x$.
In other words, we want to reduce the search space to something of the following form, using a check function as we described above.
<center>true true true true true false false false false</center>
We want to find the point at which `true` becomes `false`.
Below, we present two algorithms for binary search. The first implementation may be more intuitive, because it's closer to the binary search most students learned, while the second implementation is shorter.
(pseudocode)
If instead we're looking for the minimum `x` that satisfies some condition, then we can binary search if `check(x)` satisfies both of the following conditions:
- If `check(x)` is true, then `check(y)` is true for all $y \geq x$.
- If `check(x)` is false, then `check(y)` is false for all $y \leq x$.
The binary search function for this is very similar. Find the maximum value of $x$ such that `check(x)` is false with the algorithm above, and return $x+1$.
## Example: [CF 577 Div. 2 C](https://codeforces.com/contest/1201/problem/C)
Given an array `arr` of $n$ integers, where $n$ is odd, we can perform the following operation on it $k$ times: take any element of the array and increase it by $1$. We want to make the median of the array as large as possible, after $k$ operations.
Constraints: $1 \leq n \leq 2 \cdot 10^5, 1 \leq k \leq 10^9$ and $n$ is odd.
The solution is as follows: we first sort the array in ascending order. Then, we binary search for the maximum possible median. We know that the number of operations required to raise the median to $x$ increases monotonically as $x$ increases, so we can use binary search. For a given median value $x$, the number of operations required to raise the median to $x$ is
$$\sum_{i=(n+1)/2}^{n} \max(0, x - \text{arr[i]})$$
If this value is less than or equal to $k$, then $x$ can be the median, so our check function returns true. Otherwise, $x$ cannot be the median, so our check function returns false.
The solution codes use the second implementation of binary search.
Java:
```java
static int n;
static long k;
static long[] arr;
public static void main(String[] args) {
n = r.nextInt(); k = r.nextLong();
arr = new long[n];
for(int i = 0; i < n; i++){
arr[i] = r.nextLong();
}
Arrays.sort(arr);
pw.println(search());
pw.close();
}
// binary searches for the correct answer
static long search(){
long pos = 0; long max = (long)2E9;
for(long a = max; a >= 1; a /= 2){
while(check(pos+a)) pos += a;
}
return pos;
}
// checks whether the number of given operations is sufficient
// to raise the median of the array to x
static boolean check(long x){
long operationsNeeded = 0;
for(int i = (n-1)/2; i < n; i++){
operationsNeeded += Math.max(0, x-arr[i]);
}
if(operationsNeeded <= k){ return true; }
else{ return false; }
}
```
C++:
```cpp
int n;
long long k;
vector<long long> v;
// checks whether the number of given operations is sufficient
// to raise the median of the array to x
bool check(long long x){
long long operationsNeeded = 0;
for(int i = (n-1)/2; i < n; i++){
operationsNeeded += max(0, x-v[i]);
}
if(operationsNeeded <= k) return true;
else return false;
}
// binary searches for the correct answer
long long search(){
long long pos = 0; long long max = 2E9;
for(long long a = max; a >= 1; a /= 2){
while(check(pos+a)) pos += a;
}
return pos;
}
int main() {
cin >> n >> k;
for(int i = 0; i < n; i++){
int t;
cin >> t;
v.push_back(t);
}
sort(v.begin(), v.end());
cout << search() << '\n';
}
```
### Problems
- USACO Silver
- [Moo Buzz](http://www.usaco.org/index.php?page=viewproblem2&cpid=966)
- [Cow Dance Show](http://www.usaco.org/index.php?page=viewproblem2&cpid=690)
- binary search on $K$ and simulate
- [Convention](http://www.usaco.org/index.php?page=viewproblem2&cpid=858)
- determine whether $M$ buses suffice if every cow waits at most $T$ minutes
- use a greedy strategy (applies to next two problems as well)
- [Angry Cows](http://usaco.org/index.php?page=viewproblem2&cpid=594)
- check in $O(N)$ how many haybales you can destroy with fixed radius $R$
- [Social Distancing](http://www.usaco.org/index.php?page=viewproblem2&cpid=1038)
- check in $O(N+M)$ how many cows you can place with distance $D$
- [Loan Repayment](http://www.usaco.org/index.php?page=viewproblem2&cpid=991)
- requires some rather tricky analysis to speed up naive $O(N\log N)$ solution
- CF
- [The Meeting Place Cannot Be Changed](http://codeforces.com/contest/782/problem/B) [](48)
- [Preparing for Merge Sort](http://codeforces.com/contest/847/problem/B) [](53)
- [Level Generation](http://codeforces.com/problemset/problem/818/F) [](54)
- [Packmen](http://codeforces.com/contest/847/problem/E) [](57)
- [Office Keys](http://codeforces.com/problemset/problem/830/A) [](60)

View file

@ -1,148 +1,9 @@
---
slug: /bronze/containers
title: Built-In C++ Containers
id: containers-silver
title: Built-In C++ Containers (Silver)
author: Darren Yao
order: 4
---
Introduces the data structures in the C++ standard library that are frequently used in competitive programming.
<!-- END DESCRIPTION -->
A **data structure** determines how data is stored (is it sorted? indexed? what operations does it support?). Each data structure supports some operations efficiently, while other operations are either inefficient or not supported at all.
# Containers
The C++ standard library data structures are designed to store any type of data. We put the desired data type within the `<>` brackets when declaring the data structure, as follows:
```cpp
vector<string> v;
```
This creates a `vector` structure that only stores objects of type `string`.
For our examples below, we will primarily use the `int` data type, but note that you can use any data type including `string` and user-defined structures.
Essentially every standard library data structure supports the `size()` method, which returns the number of elements in the data structure, and the `empty()` method, which returns `true` if the data structure is empty, and `false` otherwise.
## Dynamic Arrays
You're probably already familiar with regular (static) arrays. Now, there are also dynamic arrays (`vector` in C++) that support all the functions that a normal array does, and can resize itself to accommodate more elements. In a dynamic array, we can also add and delete elements at the end in $O(1)$ time.
For example, the following code creates a dynamic array and adds the numbers $1$ through $10$ to it:
```cpp
vector<int> v;
for(int i = 1; i <= 10; i++){
v.push_back(i);
}
```
When declaring a dynamic array we can give it an initial size, so it doesn't resize itself as we add elements to it. The following code initializes a `vector` with initial size $30$:
```cpp
vector<int> v(30);
```
However, we need to be careful that we only add elements to the end of the `vector`; insertion and deletion in the middle of the `vector` is $O(n)$.
```cpp
vector<int> v;
v.push_back(2); // [2]
v.push_back(3); // [2, 3]
v.push_back(7); // [2, 3, 7]
v.push_back(5); // [2, 3, 7, 5]
v[1] = 4; // sets element at index 1 to 4 -> [2, 4, 7, 5]
v.erase(v.begin() + 1); // removes element at index 1 -> [2, 7, 5]
// this remove method is O(n); to be avoided
v.push_back(8); // [2, 7, 5, 8]
v.erase(v.end()-1); // [2, 7, 5]
// here, we remove the element from the end of the list; this is O(1).
v.push_back(4); // [2, 7, 5, 4]
v.push_back(4); // [2, 7, 5, 4, 4]
v.push_back(9); // [2, 7, 5, 4, 4, 9]
cout << v[2]; // 5
v.erase(v.begin(), v.begin()+3); // [4, 4, 9]
// this erases the first three elements; O(n)
```
To iterate through a static or dynamic array, we can use either the regular for loop or the for-each loop.
```cpp
vector<int> v;
v.push_back(1); v.push_back(7); v.push_back(4); v.push_back(5); v.push_back(2);
int arr[] = {1, 7, 4, 5, 2};
for(int i = 0; i < v.size(); i++){
cout << v[i] << " ";
}
cout << endl;
for(int element : arr){
cout << element << " ";
}
cout << endl;
```
In order to sort a dynamic array, use `sort(v.begin(), v.end())` (or `sort(begin(v),end(v))`), whereas static arrays require `sort(arr, arr + N)` where $N$ is the number of elements to be sorted. The default sort function sorts the array in ascending order.
In array-based contest problems, we'll use one-, two-, and three-dimensional static arrays most of the time. However, we can also have static arrays of dynamic arrays, dynamic arrays of static arrays, and so on. Usually, the choice between a static array and a dynamic array is just personal preference.
## Iterators
An **iterator** allows you to traverse a container by pointing to an object within the container (although they are **not** the same thing as pointers). For example, `vector.begin()` returns an iterator pointing to the first element of the vector. Apart from the standard way of traversing a vector (by treating it as an array), you can also use iterators:
```cpp
for (vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
cout << *it; //prints the values in the vector using the pointer
}
```
C++11 and later versions can automatically infer the type of an object if you use the keyword `auto`. This means that you can replace `vector<int>::iterator` with `auto` or `int` with `auto` in the for-each loop.
```cpp
for(auto element : v) {
cout << element; //prints the values in the vector
}
```
## Stacks and the Various Types of Queues
### [Stacks](http://www.cplusplus.com/reference/stack/stack/)
A stack is a **Last In First Out** (LIFO) data structure that supports three operations, all in $O(1)$ time:
- `push`: adds an element to the top of the stack
- `pop`: removes an element from the top of the stack
- `top`: retrieves the element at the top without removing it
Think of it like a real-world stack of papers (or cards).
```cpp
stack<int> s;
s.push(1); // [1]
s.push(13); // [1, 13]
s.push(7); // [1, 13, 7]
cout << s.top() << endl; // 7
s.pop(); // [1, 13]
cout << s.size() << endl; // 2
```
### [Queues](http://www.cplusplus.com/reference/queue/queue/ )
A queue is a First In First Out (FIFO) data structure that supports three operations, all in $O(1)$ time.
- `push`: insertion at the back of the queue
- `pop`, deletion from the front of the queue
- `front`: which retrieves the element at the front without removing it.
```cpp
queue<int> q;
q.push(1); // [1]
q.push(3); // [3, 1]
q.push(4); // [4, 3, 1]
q.pop(); // [4, 3]
cout << q.front() << endl; // 3
```
### [Deques](http://www.cplusplus.com/reference/deque/deque/)
A deque (usually pronounced "deck") stands for double ended queue and is a combination of a stack and a queue, in that it supports $O(1)$ insertions and deletions from both the front and the back of the deque. The four methods for adding and removing are `push_back`, `pop_back`, `push_front`, and `pop_front`. Not very common in Bronze / Silver.
@ -286,4 +147,4 @@ ms.erase(ms.find(9));
cout << ms.count(9) << '\n'; // 2
ms.erase(9);
cout << ms.count(9) << '\n'; // 0
```
```

115
content/4_Silver/Cyc.md Normal file
View file

@ -0,0 +1,115 @@
---
id: cyc
title: Cycle Detection & Functional Graphs
author: Siyong Huang
prerequisites:
-
- Silver - Depth First Search
---
<module-excerpt>
A *cycle* is a non-empty path of distinct edges that start and end at the same node.
</module-excerpt>
*Cycle detection* determines properties of cycles in a directed or undirected graph, such as whether each node of the graph is part of a cycle or just checking whether a cycle exists.
A related topic is **strongly connected components**, a platinum level concept.
### Functional Graphs
Links:
- CPH 16.3: successor paths
- CPH 16.4: cycle detection in successor graph
In silver-level directed cycle problems, it is generally the case that each node has exactly one edge going out of it. This is known as a **successor graph** or a **functional graph.**
The following sample code counts the number of cycles in such a graph. The "stack" contains nodes that can reach the current node. If the current node points to a node `v` on the stack (`on_stack[v]` is true), then we know that a cycle has been created. However, if the current node points to a node `v` that has been previously visited but is not on the stack, then we know that the current chain of nodes points into a cycle that has already been considered.
```cpp
//UNTESTED
//Each node points to next_node[node]
bool visited[MAXN], on_stack[MAXN];
int number_of_cycles = 0, next_node[MAXN];
void dfs(int n)
{
visited[n] = on_stack[n] = true;
int u = next_node[n];
if(on_stack[u])
number_of_cycles++;
else if(!visited[u])
dfs(u);
on_stack[n] = false;
}
int main()
{
//read input, etc
for(int i = 1;i <= N;i++)
if(!visited[i])
dfs(i);
}
```
The same general idea is implemented below to find any cycle in a directed graph (if one exists).
```cpp
//UNTESTED
bool visited[MAXN], on_stack[MAXN];
vector<int> adj[MAXN];
vector<int> cycle;
bool dfs(int n)
{
visited[n] = on_stack[n] = true;
for(int u:adj[n])
{
if(on_stack[u])
return cycle.push_back(v), cycle.push_back(u), on_stack[n] = on_stack[u] = false, true;
else if(!visited[u])
{
if(dfs(u))
if(on_stack[n])
return cycle.push_back(n), on_stack[n] = false, true;
else
return false;
if(!cycle.empty())
return false;
}
}
on_stack[n] = false;
return false;
}
int main()
{
//take input, etc
for(int i = 1;cycle.empty() && i <= N;i++)
dfs(i);
if(cycle.empty())
printf("No cycle found!\n");
else
{
reverse(cycle.begin(), cycle.end());
printf("Cycle of length %u found!\n", cycle.size());
for(int n : cycle) printf("%d ", n);
printf("\n");
}
}
```
### Problems
- [Codeforces 1020B. Badge (Very Easy)](https://codeforces.com/contest/1020/problem/B)
- Try to solve the problem in O(N)!
- [The Bovine Shuffle (Normal)](http://usaco.org/index.php?page=viewproblem2&cpid=764)
- [Swapity Swapity Swap (Very Hard)](http://www.usaco.org/index.php?page=viewproblem2&cpid=1014)
- [CSES Round Trip (undirected cycle)](https://cses.fi/problemset/task/1669)
- [CSES Round Trip II (directed cycle)](https://cses.fi/problemset/task/1678)
- POI
- [Mafia](https://szkopul.edu.pl/problemset/problem/w3YAoAT3ej27YeiaNWjK57_G/site/?key=statement)
- [Spies](https://szkopul.edu.pl/problemset/problem/r6tMTfvQFPAEfQioYMCQndQe/site/?key=statement)
- [Frog](https://szkopul.edu.pl/problemset/problem/qDH9CkBHZKHY4vbKRBlXPrA7/site/?key=statement)

View file

@ -1,28 +1,20 @@
---
slug: /silver/dfs
title: "Depth First Search"
id: dfs
title: Depth First Search
author: Siyong Huang
order: 8
prerequisites:
-
- Bronze - Introduction to Graphs
---
- Introduction to Graphs
- Depth First Search (DFS)
<module-excerpt>
- Depth First Search (DFS)
- Flood Fill
- Graph Two-Coloring
- Cycle Detection
<!-- END DESCRIPTION -->
## Introduction to Graphs
- Recommended
- CPH 11
- [CSAcademy Graph Intro](https://csacademy.com/lesson/introduction_to_graphs)
- [CSAcademy Graph Representations](https://csacademy.com/lesson/graph_representation)
- Usually, adjacency lists are used.
- Additional
- [Topcoder Graphs Pt 1](https://www.topcoder.com/community/data-science/data-science-tutorials/introduction-to-graphs-and-their-data-structures-section-1/)
- [Topcoder Graphs Pt 2](https://www.topcoder.com/community/data-science/data-science-tutorials/introduction-to-graphs-and-their-data-structures-section-2/)
</module-excerpt>
## Depth First Search (DFS)
@ -36,9 +28,10 @@ order: 8
- CPH 12.1
- [CSAcademy DFS](https://csacademy.com/lesson/depth_first_search/)
- Additional:
- [CPC.7](https://github.com/SuprDewd/T-414-AFLV/tree/master/07_graphs_1)
- [cp-algo DFS](https://cp-algorithms.com/graph/depth-first-search.html)
- hard to parse if this is your first time learning about DFS
- [CPC.7](https://github.com/SuprDewd/T-414-AFLV/tree/master/07_graphs_1)
- [Topcoder Graphs Pt 2](https://www.topcoder.com/community/data-science/data-science-tutorials/introduction-to-graphs-and-their-data-structures-section-2/)
### Problems
@ -54,11 +47,16 @@ order: 8
- [Moocast, Silver (Easy)](http://usaco.org/index.php?page=viewproblem2&cpid=668)
- [Pails (Normal)](http://usaco.org/index.php?page=viewproblem2&cpid=620)
- [Milk Visits (Normal)](http://www.usaco.org/index.php?page=viewproblem2&cpid=968)
- [Count Cross](http://usaco.org/index.php?page=viewproblem2&cpid=716)
- [Wormhole Sort (Normal)](http://www.usaco.org/index.php?page=viewproblem2&cpid=992)
- also binary search on the answer
- [Fence Planning](http://usaco.org/index.php?page=viewproblem2&cpid=944)
- [Moo Particle](http://www.usaco.org/index.php?page=viewproblem2&cpid=1040)
- Other
- [POI Hotels](https://szkopul.edu.pl/problemset/problem/gDw3iFkeVm7ZA3j_16-XR7jI/site/?key=statement) [](61)
- [Kattis Birthday Party (Easy)](https://open.kattis.com/problems/birthday)
- DFS with each edge removed
## Flood Fill
@ -77,12 +75,16 @@ order: 8
- [Ice Perimeter (Easy)](http://usaco.org/index.php?page=viewproblem2&cpid=895)
- [Switching on the Lights (Normal)](http://www.usaco.org/index.php?page=viewproblem2&cpid=570)
- [Build Gates (Normal)](http://www.usaco.org/index.php?page=viewproblem2&cpid=596)
- [Milk Pails (Normal)](http://usaco.org/index.php?page=viewproblem2&cpid=620)
- [Where's Bessie?](http://usaco.org/index.php?page=viewproblem2&cpid=740)
- [Why Did the Cow Cross the Road III, Silver (Normal)](http://usaco.org/index.php?page=viewproblem2&cpid=716)
- [Multiplayer Moo (Hard)](http://usaco.org/index.php?page=viewproblem2&cpid=836)
- [Snow Boots (Hard)](http://usaco.org/index.php?page=viewproblem2&cpid=811)
- [Mooyo Mooyo](http://usaco.org/index.php?page=viewproblem2&cpid=860)
## Graph Two-Coloring
*Graph two-colorings* is assigning a boolean value to each node of the graph, dictated by the edge configuration
*Graph two-coloring* refers to assigning a boolean value to each node of the graph, dictated by the edge configuration
The most common example of a two-colored graph is a *bipartite graph*, in which each edge connects two nodes of opposite colors.
- [CSES Building Teams](https://cses.fi/problemset/task/1668)
@ -119,107 +121,4 @@ void dfs(int node)
### Problems
- [CF Bipartiteness](http://codeforces.com/contest/862/problem/B) [](49)
- [The Great Revegetation (Normal)](http://usaco.org/index.php?page=viewproblem2&cpid=920)
## Cycle Detection
A *cycle* is a non-empty path of distinct edges that start and end at the same node. *Cycle detection* determines properties of cycles in a directed or undirected graph, such as whether each node of the graph is part of a cycle or just checking whether a cycle exists.
A related topic is **strongly connected components**, a platinum level concept.
### Functional Graphs
Links:
- CPH 16.3: successor paths
- CPH 16.4: cycle detection in successor graph
In silver-level directed cycle problems, it is generally the case that each node has exactly one edge going out of it. This is known as a **successor graph** or a **functional graph.**
The following sample code counts the number of cycles in such a graph. The "stack" contains nodes that can reach the current node. If the current node points to a node `v` on the stack (`on_stack[v]` is true), then we know that a cycle has been created. However, if the current node points to a node `v` that has been previously visited but is not on the stack, then we know that the current chain of nodes points into a cycle that has already been considered.
```cpp
//UNTESTED
//Each node points to next_node[node]
bool visited[MAXN], on_stack[MAXN];
int number_of_cycles = 0, next_node[MAXN];
void dfs(int n)
{
visited[n] = on_stack[n] = true;
int u = next_node[n];
if(on_stack[u])
number_of_cycles++;
else if(!visited[u])
dfs(u);
on_stack[n] = false;
}
int main()
{
//read input, etc
for(int i = 1;i <= N;i++)
if(!visited[i])
dfs(i);
}
```
The same general idea is implemented below to find any cycle in a directed graph (if one exists).
```cpp
//UNTESTED
bool visited[MAXN], on_stack[MAXN];
vector<int> adj[MAXN];
vector<int> cycle;
bool dfs(int n)
{
visited[n] = on_stack[n] = true;
for(int u:adj[n])
{
if(on_stack[u])
return cycle.push_back(v), cycle.push_back(u), on_stack[n] = on_stack[u] = false, true;
else if(!visited[u])
{
if(dfs(u))
if(on_stack[n])
return cycle.push_back(n), on_stack[n] = false, true;
else
return false;
if(!cycle.empty())
return false;
}
}
on_stack[n] = false;
return false;
}
int main()
{
//take input, etc
for(int i = 1;cycle.empty() && i <= N;i++)
dfs(i);
if(cycle.empty())
printf("No cycle found!\n");
else
{
reverse(cycle.begin(), cycle.end());
printf("Cycle of length %u found!\n", cycle.size());
for(int n : cycle) printf("%d ", n);
printf("\n");
}
}
```
### Problems
- [Codeforces 1020B. Badge (Very Easy)](https://codeforces.com/contest/1020/problem/B)
- Try to solve the problem in O(N)!
- [The Bovine Shuffle (Normal)](http://usaco.org/index.php?page=viewproblem2&cpid=764)
- [Swapity Swapity Swap (Very Hard)](http://www.usaco.org/index.php?page=viewproblem2&cpid=1014)
- [CSES Round Trip (undirected cycle)](https://cses.fi/problemset/task/1669)
- [CSES Round Trip II (directed cycle)](https://cses.fi/problemset/task/1678)
- POI
- [Mafia](https://szkopul.edu.pl/problemset/problem/w3YAoAT3ej27YeiaNWjK57_G/site/?key=statement)
- [Spies](https://szkopul.edu.pl/problemset/problem/r6tMTfvQFPAEfQioYMCQndQe/site/?key=statement)
- [Frog](https://szkopul.edu.pl/problemset/problem/qDH9CkBHZKHY4vbKRBlXPrA7/site/?key=statement)
- [The Great Revegetation (Normal)](http://usaco.org/index.php?page=viewproblem2&cpid=920)

View file

@ -0,0 +1,27 @@
---
id: data-structures
title: "Data Structures"
author: Unknown
prerequisites:
-
- Bronze - Data Structures
---
<module-excerpt>
More practice with data structures introduced in bronze.
</module-excerpt>
(set iterators?)
## USACO Problems
- Silver
- [Cities & States](http://usaco.org/index.php?page=viewproblem2&cpid=667)
- [Milk Measurement](http://usaco.org/index.php?page=viewproblem2&cpid=763)
- [Convention II](http://usaco.org/index.php?page=viewproblem2&cpid=859)
- Gold
- [Snow Boots](http://www.usaco.org/index.php?page=viewproblem2&cpid=813)
- [Springboards](http://www.usaco.org/index.php?page=viewproblem2&cpid=995)
- hard?

179
content/4_Silver/Greedy.md Normal file
View file

@ -0,0 +1,179 @@
---
id: greedy
title: "Greedy Algorithms"
author: Darren Yao
prerequisites:
-
- Silver - Sorting with Custom Comparators
---
<module-excerpt>
**Greedy** algorithms select the optimal choice at each step instead of looking at the solution space as a whole. This reduces the problem to a smaller problem at each step.
</module-excerpt>
Greedy does not refer to a single algorithm, but rather a way of thinking that is applied to problems. There's no one way to do greedy algorithms. Hence, we use a selection of well-known examples to help you understand the greedy paradigm.
Usually, when using a greedy algorithm, there is a heuristic or value function that determines which choice is considered most optimal. Usually (but not always) some sorting step is involved.
## Additional Resources
- CPH 6
- [CPC.5](https://github.com/SuprDewd/T-414-AFLV/tree/master/05_greedy_algorithms)
## Example: Studying Algorithms
### Statement
Steph wants to improve her knowledge of algorithms over winter break. She has a total of $X$ ($1 \leq X \leq 10^4$) minutes to dedicate to learning algorithms. There are $N$ ($1 \leq N \leq 100$) algorithms, and each one of them requires $a_i$ ($1 \leq a_i \leq 100$) minutes to learn. Find the maximum number of algorithms she can learn.
### Solution
The first observation we make is that Steph should prioritize learning algorithms from easiest to hardest; in other words, start with learning the algorithm that requires the least amount of time, and then choose further algorithms in increasing order of time required. Let's look at the following example:
$$X = 15, \qquad N = 6, \qquad a_i = \{ 4, 3, 8, 4, 7, 3 \}$$
After sorting the array, we have $\{ 3, 3, 4, 4, 7, 8 \}$. Within the maximum of 15 minutes, Steph can learn four algorithms in a total of $3+3+4+4 = 14$ minutes.
The implementation of this algorithm is very simple. We sort the array, and then take as many elements as possible while the sum of times of algorithms chosen so far is less than $X$. Sorting the array takes $O(N \log N)$ time, and iterating through the array takes $O(N)$ time, for a total time complexity of $O(N \log N)$.
```java
// read in the input, store the algorithms in int[] algorithms
Arrays.sort(algorithms);
int count = 0; // number of minutes used so far
int i = 0;
while(count + algorithms[i] <= x){
// while there is enough time, learn more algorithms
count += algorithms[i];
i++;
}
pw.println(i); // print the ans
pw.close();
```
## The Scheduling Problem
There are $N$ events, each described by their starting and ending times. Jason would like to attend as many events as possible, but he can only attend one event at a time, and if he chooses to attend an event, he must attend the entire event. Traveling between events is instantaneous.
### Bad Greedy: Earliest Starting Next Event
One possible ordering for a greedy algorithm would always select the next possible event that begins as soon as possible. Let's look at the following example, where the selected events are highlighted in red:
<!-- \begin{center}
\begin{tikzpicture}[ultra thick]
\draw[red](1, 2.5) -- (4, 2.5);
\draw(2, 2) -- (5, 2);
\draw[red](5, 1.5) -- (7, 1.5);
\draw(6, 1) -- (7, 1);
\end{tikzpicture}
\end{center} -->
In this example, the greedy algorithm selects two events, which is optimal. However, this doesn't always work, as shown by the following counterexample:
<!-- \begin{center}
\begin{tikzpicture}[ultra thick]
\draw[red](1, 2.5) -- (10, 2.5);
\draw(2, 2) -- (5, 2);
\draw(6, 1.5) -- (7, 1.5);
\draw(8, 1) -- (11, 1);
\end{tikzpicture}
\end{center} -->
In this case, the greedy algorithm selects to attend only one event. However, the optimal solution would be the following:
<!-- \begin{center}
\begin{tikzpicture}[ultra thick]
\draw(1, 2.5) -- (10, 2.5);
\draw[red](2, 2) -- (5, 2);
\draw[red](6, 1.5) -- (7, 1.5);
\draw[red](8, 1) -- (11, 1);
\end{tikzpicture}
\end{center} -->
### Correct Greedy: Earliest Ending Next Event
Instead, we can select the event that ends as early as possible. This correctly selects the three events.
<!-- \begin{center}
\begin{tikzpicture}[ultra thick]
\draw(1, 2.5) -- (10, 2.5);
\draw[red](2, 2) -- (5, 2);
\draw[red](6, 1.5) -- (7, 1.5);
\draw[red](8, 1) -- (11, 1);
\end{tikzpicture}
\end{center} -->
In fact, this algorithm always works. A brief explanation of correctness is as follows. If we have two events $E_1$ and $E_2$, with $E_2$ ending later than $E_1$, then it is always optimal to select $E_1$. This is because selecting $E_1$ gives us more choices for future events. If we can select an event to go after $E_2$, then that event can also go after $E_1$, because $E_1$ ends first. Thus, the set of events that can go after $E_2$ is a subset of the events that can go after $E_1$, making $E_1$ the optimal choice.
For the following code, let's say we have the array `events` of events, which each contain a start and an end point. We'll be using the following static class to store each event (a review of the previous chapter!)
```java
static class Event implements Comparable<Event>{
int start; int end;
public Event(int s, int e){
start = s; end = e;
}
public int compareTo(Event e){
return Integer.compare(this.end, e.end);
}
}
```
```java
// read in the input, store the events in Event[] events.
Arrays.sort(events); // sorts by comparator we defined above
int currentEventEnd = -1; // end of event currently attending
int ans = 0; // how many events were attended?
for(int i = 0; i < n; i++){ // process events in order of end time
if(events[i].start >= currentEventEnd){ // if event can be attended
// we know that this is the earliest ending event that we can attend
// because of how the events are sorted
currentEventEnd = events[i].end;
ans++;
}
}
pw.println(ans);
pw.close();
```
## When Greedy Fails
We'll provide a few common examples of when greedy fails, so that you can avoid falling into obvious traps and wasting time getting wrong answers in contest.
### Coin Change
This problem gives several coin denominations, and asks for the minimum number of coins needed to make a certain value. Greedy algorithms can be used to solve this problem only in very specific cases (it can be proven that it works for the American as well as the Euro coin systems). However, it doesn't work in the general case. For example, let the coin denominations be $\{1, 3, 4\}$, and say the value we want is 6. The optimal solution is $\{3, 3\}$, which requires only two coins, but the greedy method of taking the highest possible valued coin that fits in the remaining denomination gives the solution $\{4, 1, 1\}$, which is incorrect.
### Knapsack
The knapsack problem gives a number of items, each having a weight and a value, and we want to choose a subset of these items. We are limited to a certain weight, and we want to maximize the value of the items that we take.
Let's take the following example, where we have a maximum capacity of 4:
<!-- \begin{center}
\begin{tabular}{c c c c}
\toprule
Item & Weight & Value & Value Per Weight \\
\midrule
A & 3 & 18 & 6 \\
B & 2 & 10 & 5 \\
C & 2 & 10 & 5 \\
\bottomrule
\end{tabular}
\end{center} -->
If we use greedy based on highest value first, we choose item A and then we are done, as we don't have remaining weight to fit either of the other two. Using greedy based on value per weight again selects item A and then quits. However, the optimal solution is to select items B and C, as they combined have a higher value than item A alone. In fact, there is no working greedy solution. The solution to this problem uses **dynamic programming**, which is covered in gold.
# Problems
- USACO Silver
- [Lemonade Line](http://usaco.org/index.php?page=viewproblem2&cpid=835)
- [Why Did the Cow Cross the Road](http://www.usaco.org/index.php?page=viewproblem2&cpid=714)
- first step: sort!
- [Berry Picking](http://www.usaco.org/index.php?page=viewproblem2&cpid=990)
- [Rest Stops](http://www.usaco.org/index.php?page=viewproblem2&cpid=810)
- [High Card Wins](http://usaco.org/index.php?page=viewproblem2&cpid=571)
- Misc
- [Sure Bet](https://csacademy.com/contest/archive/task/sure-bet/)
- [Did you Mean...](http://codeforces.com/contest/860/problem/A)
- [Permutation](http://codeforces.com/problemset/problem/864/D)
- [Bus](http://codeforces.com/problemset/problem/864/C)
- [Kayaking](http://codeforces.com/problemset/problem/863/B)

View file

@ -0,0 +1,89 @@
---
id: intro-sorting
title: "Introduction to Sorting"
author: Siyong Huang, Michael Cao, Nathan Chen
---
<module-excerpt>
Introduces sorting, binary search, coordinate compression.
</module-excerpt>
**Sorting** is exactly what it sounds like: arranging items in some particular order.
## Additional Resources
- CPH 3 (once again, very good)
## Sorting Algorithms
(why are these important?)
There are many sorting algorithms, here are some sources to learn about the popular ones:
- [Bubble Sort](https://www.hackerrank.com/challenges/ctci-bubble-sort/problem)
- [Out of Sorts (Silver)](http://www.usaco.org/index.php?page=viewproblem2&cpid=834)
- hard!
- [Quicksort](https://www.hackerearth.com/practice/algorithms/sorting/quick-sort/tutorial/)
- [Mergesort](https://www.hackerearth.com/practice/algorithms/sorting/merge-sort/tutorial/)
## Library Sorting
- C++:
- [std::sort Documentation](https://en.cppreference.com/w/cpp/algorithm/sort)
- [C++ Tricks (First Two Related To Sorting)](https://codeforces.com/blog/entry/74684)
- [std::stable\_sort documentation](http://www.cplusplus.com/reference/algorithm/stable_sort/)
- Java:
- [Arrays.sort Documentation](https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#sort(java.lang.Object[]))
- [Breaking Java Arrays.sort()](https://codeforces.com/blog/entry/4827)
- no longer works, but see [this one](https://codeforces.com/contest/1324/hacks/625031/test) instead.
- to avoid getting hacked, [shuffle](https://pastebin.com/k6gCRJDv) the array beforehand.
- Python:
- [Sorted Documentation](https://docs.python.org/3/howto/sorting.html)
## Binary Search
[Binary search](https://en.wikipedia.org/wiki/Binary_search_algorithm) can be used on monotonic (what's that?) functions for a logarithmic runtime.
Here is a very basic form of binary search:
> Find an element in a sorted array of size $N$ in $O(\log N)$ time.
Other variations are similar, such as the following:
> Given $K$, find the largest element less than $K$ in a sorted array.
### Tutorial
- CSES 3.3
- [CSAcademy Binary Search](https://csacademy.com/lesson/binary_search)
- [Topcoder Binary Search](https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/)
- [KhanAcademy Binary Search](https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/binary-search)
- [GeeksForGeeks](https://www.geeksforgeeks.org/binary-search/)
### Library Functions to do Binary Search
#### Java
- [Arrays.binarySearch](https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html)
- [Collections.binarySearch](https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html)
#### C++
- [lower_bound](http://www.cplusplus.com/reference/algorithm/lower_bound/)
- [upper_bound](http://www.cplusplus.com/reference/algorithm/upper_bound/)
## Example (Coordinate Compression)
Another useful application of sorting is coordinate compression, which takes some points and reassigns them to remove wasted space. Let's consider the USACO Silver problem [Counting Haybales](http://www.usaco.org/index.php?page=viewproblem2&cpid=666):
> Farmer John has just arranged his $N$ haybales $(1\le N \le 100,000)$ at various points along the one-dimensional road running across his farm. To make sure they are spaced out appropriately, please help him answer $Q$ queries ($1 \le Q \le 100,000$), each asking for the number of haybales within a specific interval along the road.
However, each of the points are in the range $0 \ldots 1,000,000,000$, meaning you can't store locations of haybales in, for instance, a boolean array. However, let's place all of the locations of the haybales into a list and sort it.
(fix this part)
Now, we can map distinct points to smaller integers without gaps. For example, if the haybales existed at positions $[1, 4, 5, 9]$ and queries were $(1, 2)$ and $(4, 6)$, we can place the integers together and map them from $[1, 2, 4, 5, 6, 9] \rightarrow [1, 2, 3, 4, 5, 6]$. This effectively transforms the haybale positions into $[1, 3, 4, 6]$ and the queries into $1, 2$ and $3, 5$.
By compressing queries and haybale positions, we've transformed the range of points to $0 \ldots N + 2Q$, allowing us to store prefix sums to effectively query for the number of haybales in a range.

View file

@ -0,0 +1,54 @@
---
id: prefix-sums
title: "Prefix Sums"
author: Darren Yao, Eric Wei
---
<module-excerpt>
Let's say we have a one-indexed integer array $\texttt{arr}$ of size $N$ and we want to answer $Q$ queries of the following form: compute $\texttt{arr[L]+arr[L+1]+}\cdots\texttt{+arr[R]}$.
</module-excerpt>
## Standard
- [CSES Range Sum Queries I](https://cses.fi/problemset/task/1646)
- [LeetCode Find Pivot Index](https://leetcode.com/problems/find-pivot-index/)
## Additional Resources
- CPH 9.1
## Tutorial
Let's use the following example with $N = 6$:
todo convert the below to array because tabular isn't supported
```
\begin{center}
\begin{tabular}{ c | c c c c c c c }
\toprule
Index $i$ & \color{gray}{0} & 1 & 2 & 3 & 4 & 5 & 6 \\
\texttt{arr[i]} & \color{gray}{0} & 1 & 6 & 4 & 2 & 5 & 3 \\
\bottomrule
\end{tabular}
\end{center}
```
Naively, for every query, we can iterate through all entries from index $a$ to index $b$ to add them up. Since we have $Q$ queries and each query requires a maximum of $O(N)$ operations to calculate the sum, our total time complexity is $O(NQ)$. For most problems of this nature, the constraints will be $N, Q \leq 10^5$, so $NQ$ is on the order of $10^{10}$. This is not acceptable; it will almost always exceed the time limit.
Instead, we can use prefix sums to process these array sum queries. We designate a prefix sum array $\texttt{prefix}$. First, because we're 1-indexing the array, set $\texttt{prefix}[0]=0$, then for indices $k$ such that $1 \leq k \leq n$, define the prefix sum array as follows:
$$\texttt{prefix[k]}=\sum_{i=1}^{k} \texttt{arr[i]}$$
Basically, what this means is that the element at index $k$ of the prefix sum array stores the sum of all the elements in the original array from index $1$ up to $k$. This can be calculated easily in $O(N)$ by the following formula:
$$\texttt{prefix[k]}=\texttt{prefix[k-1]}+\texttt{arr[k]}$$
For the example case, our prefix sum array looks like this:
Now, when we want to query for the sum of the elements of $\texttt{arr}$ between (1-indexed) indices $L$ and $R$ inclusive, we can use the following formula:
$$\sum_{i=L}^{R} \texttt{arr[i]} = \sum_{i=1}^{R} \texttt{arr[i]} - \sum_{i=1}^{L-1} \texttt{arr[i]}$$

View file

@ -0,0 +1,343 @@
---
id: sorting-custom
title: "Sorting with Custom Comparators"
author: Darren Yao, Siyong Huang
prerequisites:
-
- Silver - Introduction to Sorting
---
<module-excerpt>
Both Java and C++ have built-in functions for sorting. However, if we use custom objects, or if we want to sort elements in a different order, then we'll need to use a **custom comparator**.
</module-excerpt>
## Comparators
Normally, sorting functions rely on moving objects with a lower value in front of objects with a higher value if sorting in ascending order, and vice versa if in descending order. This is done through comparing two objects at a time.
### C++
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`
- If object $x$ is greater than or equal to object $y$, return `false`
Essentially, the comparator determines whether object $x$ belongs to the left of object $y$ in a sorted ordering. A comparator **must** return false for two identical objects (not doing so results in undefined behavior and potentially RTE).
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 positive, then `compare(y, x)` should be negative 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`.
A generic way of implementing a custom comparator is to define a function. For our example, we'll use a `struct` of a Person that contains a person's height and weight, and sort in ascending order by height. A `struct` is essentially a user-defined data structure:
```cpp
struct Person {
int height;
int weight;
};
int main() {
Person p;
p.height = 60; // assigns 60 to the height of p
p.weight = 100; // assigns 100 to the weight of p
}
```
Let's say we have an array `Person arr[N]`. To sort the array, we need to make custom comparator which will be a function, and then pass the function as a parameter into the build-in sort function:
```cpp
bool cmp(Person a, Person b) {
return a.height < b.height;
}
int main() {
sort(arr, arr+N, cmp); // sorts the array in ascending order by height
}
```
If we instead wanted to sort in descending order, this is also very simple. Instead of the `cmp` function returning `return a.height < b.height;`, it should do `return a.height > b.height;`.
### Java
What a `Comparator` does is compare two objects as follows, based on our comparison criteria:
- If object $x$ is less than object $y$, return a negative number.
- If object $x$ is greater than object $y$, return a positive number.
- If object $x$ is equal to object $y$, return 0.
In addition to returning the correct number, comparators should also satisfy the following conditions:
- The function must be consistent with respect to reversing the order of the arguments: if $compare(x, y)$ is positive, then $compare(y, x)$ should be negative and vice versa.
- The function must be transitive. If $compare(x, y) > 0$ and $compare(y, z) > 0$, then $compare(x, z) > 0$. Same applies if the compare functions return negative numbers.
- Equality must be consistent. If $compare(x, y) = 0$, then $compare(x, z)$ and $compare(y, z)$ must both be positive, both negative, or both zero. Note that they don't have to be equal, they just need to have the same sign.
Java has default functions for comparing `int`, `long`, `double` types. The `Integer.compare()`, `Long.compare()`, and `Double.compare()` functions take two arguments $x$ and $y$ and compare them as described above.
Now, there are two ways of implementing this in Java: `Comparable`, and `Comparator`. They essentially serve the same purpose, but `Comparable` is generally easier and shorter to code. `Comparable` is a function implemented within the class containing the custom object, while `Comparator` is its own class. For our example, we'll use a `Person` class that contains a person's height and weight, and sort in ascending order by height.
If we use `Comparable`, we'll need to put `implements Comparable<Person>` into the heading of the class. Furthermore, we'll need to implement the `compareTo` method. Essentially, `compareTo(x)` is the `compare` function that we described above, with the object itself as the first argument, or `compare(self, x)`.
```java
static class Person implements Comparable<Person>{
int height, weight;
public Person(int h, int w){
height = h; weight = w;
}
public int compareTo(Person p){
return Integer.compare(height, p.height);
}
}
```
When using Comparable, we can just call `Arrays.sort(arr)` or `Collections.sort(list)` on the array or list as usual.
If instead we choose to use `Comparator`, we'll need to declare a second `Comparator` class, and then implement that:
```java
static class Person{
int height, weight;
public Person(int h, int w){
height = h; weight = w;
}
}
static class Comp implements Comparator<Person>{
public int compare(Person a, Person b){
return Integer.compare(a.height, b.height);
}
}
```
When using `Comparator`, the syntax for using the built-in sorting function requires a second argument: `Arrays.sort(arr, new Comp())`, or `Collections.sort(list, new Comp())`.
If we instead wanted to sort in descending order, this is also very simple. Instead of the comparing function returning `Integer.compare(x, y)` of the arguments, it should instead return `-Integer.compare(x, y)`.
### Python
There are 3 main ways to create a custom comparator in python
#### 1) Operator Overloading
<!-- Tested -->
```py
import random
class Foo:
def __init__(self, _Bar): self.Bar = _Bar
def __str__(self): return "Foo({})".format(self.Bar)
def __lt__(self, o): # lt means less than
return self.Bar < o.Bar
a = []
for i in range(8):
a.append(Foo(random.randint(1, 10)))
print(*a)
print(*sorted(a))
```
Output:
```
Foo(0) Foo(1) Foo(2) Foo(1) Foo(9) Foo(5) Foo(5) Foo(8)
Foo(0) Foo(1) Foo(1) Foo(2) Foo(5) Foo(5) Foo(8) Foo(9)
```
#### 2) Remapping Key
- This method maps an object to another comparable datatype with which to be sorted. In this case, `Foo` is sorted by the sum of its members `x` and `y`.
<!-- Tested -->
```py
import random
class Foo:
def __init__(self, _Bar, _Baz): self.Bar,self.Baz = _Bar,_Baz
def __str__(self): return "Foo({},{})".format(self.Bar, self.Baz)
a = []
for i in range(8):
a.append(Foo(random.randint(1, 9)*10, random.randint(1, 9)))
print(*a)
print(*sorted(a, key=lambda foo: foo.Bar+foo.Baz))
def key(foo):
return foo.Bar + foo.Baz
print(*sorted(a, key=key))
```
Output:
```
Foo(10,2) Foo(30,2) Foo(60,6) Foo(90,7) Foo(80,7) Foo(80,9) Foo(60,9) Foo(90,8)
Foo(10,2) Foo(30,2) Foo(60,6) Foo(60,9) Foo(80,7) Foo(80,9) Foo(90,7) Foo(90,8)
Foo(10,2) Foo(30,2) Foo(60,6) Foo(60,9) Foo(80,7) Foo(80,9) Foo(90,7) Foo(90,8)
```
#### 3) Function / Lambda
- This method defines how to compare two elements represented by an integer
- Positive: First term is greater than the second term
- Zero: First term and second term are equal
- Negative: First term is less than the second term
Note how the comparator must be converted to a `key`.
<!-- Tested -->
```py
import random
from functools import cmp_to_key
class Foo:
def __init__(self, _Bar): self.Bar = _Bar
def __str__(self): return "Foo({})".format(self.Bar)
a = []
for i in range(8):
a.append(Foo(random.randint(0, 9)))
print(*a)
print(*sorted(a, key=cmp_to_key(lambda foo1, foo2: foo1.Bar - foo2.Bar)))
def cmp(foo1, foo2):
return foo1.Bar - foo2.Bar
print(*sorted(a, key=cmp_to_key(cmp)))
```
Output:
```
Foo(0) Foo(1) Foo(2) Foo(1) Foo(9) Foo(5) Foo(5) Foo(8)
Foo(0) Foo(1) Foo(1) Foo(2) Foo(5) Foo(5) Foo(8) Foo(9)
Foo(0) Foo(1) Foo(1) Foo(2) Foo(5) Foo(5) Foo(8) Foo(9)
```
## Sorting by Multiple Criteria
Now, suppose we wanted to sort a list of `Person`s in ascending order, primarily by height and secondarily by weight. We can do this quite similarly to how we handled sorting by one criterion earlier. What the comparator function needs to do is to compare the weights if the heights are equal, and otherwise compare heights, as that's the primary sorting criterion.
### C++
```cpp
bool cmp(Person a, Person b) {
if(a.height == b.height) {
return a.weight < b.weight;
}
return a.height < b.height;
}
int main() {
sort(arr, arr+N, cmp); // sorts the array in ascending order by height and then weight if the heights are equal
}
```
Sorting with an arbitrary number of criteria is done similarly.
### Java
```java
static class Person implements Comparable<Person>{
int height, weight;
public Person(int h, int w){
height = h; weight = w;
}
public int compareTo(Person p){
if(height == p.height){
return Integer.compare(weight, p.weight);
} else {
return Integer.compare(height, p.height);
}
}
}
```
Sorting with an arbitrary number of criteria is done similarly.
An alternative way of representing custom objects is with arrays. Instead of using a custom object to store data about each person, we can simply use `int[]`, where each `int` array is of size 2, and stores pairs of {height, weight}, probably in the form of a list like `ArrayList<int[]>`. Since arrays aren't objects in the usual sense, we need to use `Comparator`. Example for sorting by the same two criteria as above:
```java
static class Comp implements Comparator<int[]>{
public int compare(int[] a, int[] b){
if(a[0] == b[0]){
return Integer.compare(a[1], b[1]);
} else {
return Integer.compare(a[0], b[0]);
}
}
}
```
I don't recommend using arrays to represent objects mostly because it's confusing, but it's worth noting that some competitors do this.
### Python
Operator Overloading can be used
<!-- Tested -->
```py
import random
class Foo:
def __init__(self, _Bar, _Baz): self.Bar,self.Baz = _Bar,_Baz
def __str__(self): return "Foo({},{})".format(self.Bar, self.Baz)
def __lt__(self, o): # sort by increasing Bar, breaking ties by decreasing Baz
if self.Bar != o.Bar: return self.Bar < o.Bar
if self.Baz != o.Baz: return self.Baz > o.Baz
return False
a = []
for i in range(8):
a.append(Foo(random.randint(1, 9), random.randint(1, 9)))
print(*a)
print(*sorted(a))
```
Output:
```
Foo(1,2) Foo(3,2) Foo(6,6) Foo(9,7) Foo(8,7) Foo(8,9) Foo(6,9) Foo(9,8)
Foo(1,2) Foo(3,2) Foo(6,9) Foo(6,6) Foo(8,9) Foo(8,7) Foo(9,8) Foo(9,7)
```
A custom comparator works as well
- Lambdas aren't shown here because they are typically used as one-liners
```py
import random
from functools import cmp_to_key
class Foo:
def __init__(self, _Bar, _Baz): self.Bar,self.Baz = _Bar,_Baz
def __str__(self): return "Foo({},{})".format(self.Bar, self.Baz)
a = []
for i in range(8):
a.append(Foo(random.randint(1, 9), random.randint(1, 9)))
print(*a)
def cmp(foo1, foo2): # Increasing Bar, breaking ties with decreasing Baz
if foo1.Bar != foo2.Bar: return -1 if foo1.Bar < foo2.Bar else 1
if foo1.Baz != foo2.Baz: return -1 if foo1.Baz > foo2.Baz else 1
return 0
print(*sorted(a, key=cmp_to_key(cmp)))
# Python automatically sorts tuples in increasing order with priority to the leftmost element
# You can sort objects by its mapping to a tuple of its elements
# The following sorts Foo by increasing Bar values, breaking ties with increasing Baz value
print(*sorted(a, key=lambda foo: (foo.Bar, foo.Baz)))
```
Output:
```
Foo(1,2) Foo(3,2) Foo(6,6) Foo(9,7) Foo(8,7) Foo(8,9) Foo(6,9) Foo(9,8)
Foo(1,2) Foo(3,2) Foo(6,9) Foo(6,6) Foo(8,9) Foo(8,7) Foo(9,8) Foo(9,7)
Foo(1,2) Foo(3,2) Foo(6,6) Foo(6,9) Foo(8,7) Foo(8,9) Foo(9,7) Foo(9,8)
```
## Problems
- [Lifeguards](http://usaco.org/index.php?page=viewproblem2&cpid=786)
- [Rental Service](http://usaco.org/index.php?page=viewproblem2&cpid=787)
- [Mountains](http://usaco.org/index.php?page=viewproblem2&cpid=896)
- [Mooyo Mooyo](http://www.usaco.org/index.php?page=viewproblem2&cpid=860)
- Not a sorting problem, but you can use sorting to simulate gravity nicely.
- Write a custom comparator (read below) which puts zeroes at the front and use `stable_sort` to keep the relative order of other elements the same.
- [Meetings](http://www.usaco.org/index.php?page=viewproblem2&cpid=967)
- hard!

View file

@ -0,0 +1,312 @@
---
id: sorting-cpp
title: "More on Sorting in C++"
author: Siyong Huang, Michael Cao, Darren Yao, Benjamin Qi
prerequisites:
-
- Bronze - Introduction to Graphs
-
- Silver - Sorting with Custom Comparators
---
<module-excerpt>
More information about sorting with custom comparators in C++. Some overlap with the previous article.
</module-excerpt>
## Additional Resources
- [fushar (C++)](http://fusharblog.com/3-ways-to-define-comparison-functions-in-cpp/)
## An Example with Graphs
Consider a graph with weighted edges (pairs of values), such as in the problem [Wormhole Sort (Silver)](http://www.usaco.org/index.php?page=viewproblem2&cpid=992). There are multiple ways to solve this problem, but all of them start by sorting the edges in nondecreasing order of weight. 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 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.
## Comparators for Sorting
There are 2 main ways to have a custom comparator in c++.
### Overloading Operator
[Why const T&?](https://stackoverflow.com/questions/11805322/why-should-i-use-const-t-instead-of-const-t-or-t)
- Pro:
- This is the easiest to implement
- Easy to work with STL
- Con:
- Only works for objects (not primitives)
- Only supports two types of comparisons (less than (<) and greater than (>))
<!-- Tested -->
```cpp
#include <bits/stdc++.h>
using namespace std;
int randint(int low, int high) {return low+rand()%(high-low);}
struct Foo
{
int Bar;
Foo(int _Bar=-1):Bar(_Bar){}
bool operator < (const Foo& foo2) const {return Bar < foo2.Bar;}
};
const int N = 8;
int main()
{
srand(69);
Foo a[N];
for(int i=0;i<N;++i) a[i] = Foo(randint(0, 20));
for(int i=0;i<N;++i) printf("(Foo: %2d) ", a[i].Bar); printf("\n");
sort(a, a+N);
for(int i=0;i<N;++i) printf("(Foo: %2d) ", a[i].Bar); printf("\n");
}
/**
Output:
(Foo: 3) (Foo: 18) (Foo: 13) (Foo: 5) (Foo: 18) (Foo: 3) (Foo: 15) (Foo: 0)
(Foo: 0) (Foo: 3) (Foo: 3) (Foo: 5) (Foo: 13) (Foo: 15) (Foo: 18) (Foo: 18)
*/
```
In the context of Wormhole Sort (uses [friend](https://www.geeksforgeeks.org/friend-class-function-cpp/)):
```cpp
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int a,b,w;
friend bool operator<(const Edge& x, const Edge& y) { return x.w < y.w; }
}; // a different way to write less than
int main() {
int M = 4;
vector<Edge> v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.push_back({a,b,w});
}
sort(begin(v),end(v));
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
/*
Input:
1 2 9
1 3 7
2 3 10
2 4 3
*/
/*
Output:
2 4 3
1 3 7
1 2 9
2 3 10
*/
```
### Function
- Pro:
- Works for both objects and primitives
- Supports many different comparators for the same object
- Con:
- More difficult to implement
- Extra care needs to be taken to support STL
We can also use [lambda expressions](https://www.geeksforgeeks.org/lambda-expression-in-c/) in C++11 or above.
<!-- Tested -->
```cpp
#include <bits/stdc++.h>
using namespace std;
int randint(int low, int high) {return low+rand()%(high-low);}
struct Foo
{
int Bar;
Foo(int _Bar=-1):Bar(_Bar){}
};
const int N = 8;
Foo a[N];
bool cmp1(Foo foo1, Foo foo2) {return foo1.Bar < foo2.Bar;}
function<bool(Foo,Foo)> cmp2 = [](Foo foo1, Foo foo2) {return foo1.Bar < foo2.Bar;}; // lambda expression
// bool(Foo,Foo) means that the function takes in two parameters of type Foo and returns bool
// "function<bool(Foo,Foo)>"" can be replaced with "auto"
int main()
{
srand(69);
printf("--- Method 1 ---\n");
for(int i=0;i<N;++i) a[i] = Foo(randint(0, 20));
for(int i=0;i<N;++i) printf("(Foo: %2d) ", a[i].Bar); printf("\n");
sort(a, a+N, [](Foo foo1, Foo foo2){return foo1.Bar<foo2.Bar;}); // lambda expression
for(int i=0;i<N;++i) printf("(Foo: %2d) ", a[i].Bar); printf("\n");
printf("--- Method 2 ---\n");
for(int i=0;i<N;++i) a[i] = Foo(randint(0, 20));
for(int i=0;i<N;++i) printf("(Foo: %2d) ", a[i].Bar); printf("\n");
sort(a, a+N, cmp1);
for(int i=0;i<N;++i) printf("(Foo: %2d) ", a[i].Bar); printf("\n");
printf("--- Method 3 ---\n");
for(int i=0;i<N;++i) a[i] = Foo(randint(0, 20));
for(int i=0;i<N;++i) printf("(Foo: %2d) ", a[i].Bar); printf("\n");
sort(a, a+N, cmp2);
for(int i=0;i<N;++i) printf("(Foo: %2d) ", a[i].Bar); printf("\n");
}
```
Output:
```
--- Method 1 ---
(Foo: 3) (Foo: 18) (Foo: 13) (Foo: 5) (Foo: 18) (Foo: 3) (Foo: 15) (Foo: 0)
(Foo: 0) (Foo: 3) (Foo: 3) (Foo: 5) (Foo: 13) (Foo: 15) (Foo: 18) (Foo: 18)
--- Method 2 ---
(Foo: 5) (Foo: 13) (Foo: 18) (Foo: 0) (Foo: 9) (Foo: 4) (Foo: 2) (Foo: 15)
(Foo: 0) (Foo: 2) (Foo: 4) (Foo: 5) (Foo: 9) (Foo: 13) (Foo: 15) (Foo: 18)
--- Method 3 ---
(Foo: 1) (Foo: 1) (Foo: 18) (Foo: 0) (Foo: 11) (Foo: 12) (Foo: 1) (Foo: 5)
(Foo: 0) (Foo: 1) (Foo: 1) (Foo: 1) (Foo: 5) (Foo: 11) (Foo: 12) (Foo: 18)
```
In the context of Wormhole Sort:
```cpp
#include <bits/stdc++.h>
using namespace std;
struct Edge { int a,b,w; };
int main() {
int M = 4;
vector<Edge> v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.push_back({a,b,w});
}
sort(begin(v),end(v),[](const Edge& x, const Edge& y) { return x.w < y.w; });
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
```
### Comparators for STL
Operator overloading works as expected for using in STL. If you are sorting elements in reverse order, you can use the STL [greater](https://en.cppreference.com/w/cpp/utility/functional/greater) comparator instead.
For function comparators, some extra care needs to be taken:
<!-- Reasonably Tested -->
```cpp
struct foo
{
//members
};
auto cmp1 = [](const foo& a, const foo& b){return /*comparator function*/;};
//This way is shorter to write, but don't forget to pass the comparator as a parameter in the constructor!
//If you need to create an array of the objects, I would either use pointers of the method shown below
set<foo, decltype(cmp1)> Set1(cmp1);
priority_queue<foo, vector<foo>, decltype(cmp1)> pq1(cmp1);
//Side Note: priority queue is sorted in REVERSE order (largest elements are first)
map<foo, bar, decltype(cmp1)> Map1(cmp1);
struct cmp2
{
bool operator () (const foo& a, const foo& b){return /*comparator function*/;}
};
//Here you do not need to pass the comparator as a parameter
//This makes it easier to create arrays of stl objects
set<foo, cmp2> Set2;
priority_queue<foo, vector<foo>, cmp2> pq2;
map<foo, bar, cmp2> Map2;
set<foo, cmp2> Set2b[100];//array of sets with the comparator
```
### Example of Comparators for Primitives
Since you cannot overload operators for primitives, you must use custom comparators.
<!-- Tested -->
```cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 8;
int a[N], b[N] = {4,8,2,3,4,1,2,4};
int main()
{
printf("--- Comparator 1 ---\n");
iota(a, a+N, 0);
sort(a, a+N, greater<int>());
//sort a in decreasing order
for(int i=0;i<N;++i) printf("a[%d] = %d\n", i, a[i]);
printf("--- Comparator 2 ---\n");
iota(a, a+N, 0);
sort(a, a+N, [](int x, int y){return b[x]<b[y]||(b[x]==b[y]&&x>y);});
//sort a by increasing values of b[i], breaking ties by decreasing index
for(int i=0;i<N;++i) printf("a[%d] = %d: b[%d] = %d\n", i, a[i], a[i], b[a[i]]);
}
/*
Output:
--- Comparator 1 ---
a[0] = 7
a[1] = 6
a[2] = 5
a[3] = 4
a[4] = 3
a[5] = 2
a[6] = 1
a[7] = 0
--- Comparator 2 ---
a[0] = 5: b[5] = 1
a[1] = 6: b[6] = 2
a[2] = 2: b[2] = 2
a[3] = 3: b[3] = 3
a[4] = 7: b[7] = 4
a[5] = 4: b[4] = 4
a[6] = 0: b[0] = 4
a[7] = 1: b[1] = 8
*/
```
Comments: Comparator 1 sorts array $a$ in decreasing order. Comparator 2 sorts array $a$ in increasing $b[a[i]]$ value, breaking ties by placing the greater index first.
## Sorting Pairs
An alternative way of representing custom objects is with the data structure `pair<int, int>`. In the above example, instead of creating a `struct`, we can simply declare an array of pairs. The sort function automatically uses the first element of the pair for comparison and the second element as a secondary point of comparison:
```cpp
pair<int, int> arr[N];
int main() {
sort(arr, arr+N);
}
```
There is no need to create a custom comparator.
```cpp
#include <bits/stdc++.h>
using namespace std;
#define f first
#define s second
int main() {
int M = 4;
vector<pair<int,pair<int,int>>> v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.push_back({w,{a,b}});
}
sort(begin(v),end(v));
for (auto e: v) cout << e.s.f << " " << e.s.s << " " << e.f << "\n";
}
```

View file

@ -1,124 +0,0 @@
---
slug: /gold/dp
title: "Introduction to Dynamic Programming"
author: Michael Cao
order: 1
prerequisites:
-
- Recursion
-
- Silver - Prefix Sums
---
**Dynamic Programming (DP)** is a very important concept which emerges in the Gold division and extends to the IOI.
<!-- END DESCRIPTION -->
[[info | Contest Tip]]
| Usually at least one problem from every gold division contest involves some sort of DP.
## Tutorial
The following tutorials serve as an introduction into the mindset of DP.
- CPH 7
- great introduction that covers most classical problems
- [Topcoder DP](https://www.topcoder.com/community/competitive-programming/tutorials/dynamic-programming-from-novice-to-advanced/)
- great for all skill levels
- [CPC.6](https://github.com/SuprDewd/T-414-AFLV/tree/master/06_dynamic_programming)
- examples with nonclassical problems
- [HackerRank DP](https://www.hackerrank.com/topics/dynamic-programming)
- also covers many classical problems
Practice makes perfect. Start by doing some classical problems (try at least one of each), as these are **must know** DP problems. Each topic starts with direct applications of the classical problems, and then some interesting variations and USACO problems which utilize the ideas. Solutions for most problems (excluding USACO) can be found on Chapter 7 of CPH.
## General
* [**Atcoder DP Contest**](https://atcoder.jp/contests/dp/tasks)
* very good!
* [CSES DP Section](https://cses.fi/problemset/list/)
* also very good!
* [Codeforces DP Problem List](http://codeforces.com/blog/entry/325)
The following USACO problems don't fall into any of the categories below. Arranged roughly in order of difficulty.
[[info | Pro Tip]]
| Sometimes it's a good idea to write a slower polynomial-time solution and then optimize it to the desired complexity (say, write $O(N^2)$ first and then speed it up to $O(N)$).
* [Hoof Paper Scissors](http://www.usaco.org/index.php?page=viewproblem2&cpid=694)
* `dp[first i games][# changes][last gesture] -> max games won`
* [Time is Mooney](http://www.usaco.org/index.php?page=viewproblem2&cpid=993)
* `dp[time][city] -> money`
* [Teamwork](http://usaco.org/index.php?page=viewproblem2&cpid=863)
* $O(NK^2)\to O(NK)$
* [Snakes](http://www.usaco.org/index.php?page=viewproblem2&cpid=945)
* `dp[first m groups][k changes] -> total sum of net sizes`
* $O(N^4)\to O(N^3)$
* [Circular Barn Revisited](http://www.usaco.org/index.php?page=viewproblem2&cpid=622)
* can brute force make your DP easier? (yes)
* [Taming the Herd](http://www.usaco.org/index.php?page=viewproblem2&cpid=815)
* `dp[consider first i entries only][last breakout in first i occurs at j][k breakouts among first i entries] -> # changes`
* [Mortal Cowmbat](http://usaco.org/index.php?page=viewproblem2&cpid=971)
* Use Floyd-Warshall, Prefix Sums
* `dp[first i letters form valid combo][last letter] -> time`
* [Stamp Painting](http://www.usaco.org/index.php?page=viewproblem2&cpid=791)
* must be $K$ consecutive with same color
* $O(NK)\to O(N)$
## Bounded and Unbounded Knapsack
* Classic
* [Unbounded Knapsack](https://www.hackerrank.com/challenges/unbounded-knapsack/problem)
* [Unordered Coin Change](https://cses.fi/problemset/task/1635)
* [Ordered Coin Change](https://cses.fi/problemset/task/1636)
* [Minimum Coins](https://cses.fi/problemset/task/1634)
* [0/1](https://www.hackerrank.com/contests/srin-aadc03/challenges/classic-01-knapsack/problem)
* [Large Capacity + Small Values](https://atcoder.jp/contests/dp/tasks/dp_e)
* Reconsider the state.
* USACO Gold
* [Fruit Feast](http://www.usaco.org/index.php?page=viewproblem2&cpid=574)
* straightforward
* [Talent Show](http://www.usaco.org/index.php?page=viewproblem2&cpid=839)
* binary search + knapsack on weight
* [Cow Poetry](http://usaco.org/index.php?page=viewproblem2&cpid=897)
* First consider the case where there are only two lines with the same class.
* Requires fast modular exponentiation for full credit.
* [Exercise](http://www.usaco.org/index.php?page=viewproblem2&cpid=1043)
* With a bit of number theory
* CF
* [Round Subset](http://codeforces.com/contest/837/problem/D) [](59)
* [Fire](http://codeforces.com/contest/864/problem/E) [](59)
## Paths on Grid (& Related)
* Classic
* Longest Common Subsequence
* [Standard](https://leetcode.com/problems/longest-common-subsequence/)
* Edit Distance
* [Standard](https://www.hackerrank.com/contests/cse-830-homework-3/challenges/edit-distance)
* Paths on a Grid
* [Count Paths](https://atcoder.jp/contests/dp/tasks/dp_h)
* USACO
* [Gold - Cow Checklist](http://www.usaco.org/index.php?page=viewproblem2&cpid=670)
* `dp[visited i Hs][visited j Gs][last cow visited] -> min energy`
* [Gold - Radio Contact](http://www.usaco.org/index.php?page=viewproblem2&cpid=598)
* similar to above
* [Gold - Why Did The Cow Cross the Road II](http://www.usaco.org/index.php?page=viewproblem2&cpid=718)
* variation on LCS
* [Old Silver - Landscaping](http://www.usaco.org/index.php?page=viewproblem2&cpid=126)
* Although the problem looks different, this is actually a direct application of edit distance.
* [Old Gold - Palindromic Paths](http://www.usaco.org/index.php?page=viewproblem2&cpid=553)
* What are some properties of the answer?
* Other
* [TC Interleaving Parentheses](https://community.topcoder.com/stat?c=problem_statement&pm=14635&rd=16933)
* [K-Ordered LCS](https://www.hackerearth.com/problem/algorithm/mancunian-and-k-ordered-lcs-e6a4b8c6/)
* [CSA Wrong Brackets](https://csacademy.com/contest/round-51/task/wrong-brackets/) [](69)
## Longest Increasing Subsequence
(add?)
* [LIS in Quadratic Time](https://leetcode.com/problems/longest-increasing-subsequence/)
* Try to improve to $O(N\log N)$.
* [Sort It Out (USACO Platinum)](http://www.usaco.org/index.php?page=viewproblem2&cpid=865)
* Challenging!

View file

@ -1,35 +0,0 @@
---
slug: /gold/toposort
title: "Topological Sort"
author: Benjamin Qi
order: 3
prerequisites:
-
- Gold - Breadth First Search
---
A [topological sort](https://en.wikipedia.org/wiki/Topological_sorting) of a directed graph is a linear ordering of its vertices such that for every directed edge $u\to v$ from vertex $u$ to vertex $v$, $u$ comes before $v$ in the ordering.
## Example Problems
- [CSES Course Schedule](https://cses.fi/problemset/task/1679)
- [CSES Longest Flight Route](https://cses.fi/problemset/task/1680)
- [CSES Game Routes](https://cses.fi/problemset/task/1681)
## Tutorial
- CPH 16.1, 16.2
- DFS
- [cp-algorithms](https://cp-algorithms.com/graph/topological-sort.html)
- DFS
- [CSAcademy](https://csacademy.com/lesson/topological_sorting)
- both BFS, DFS
## Problems
- USACO Gold
- [Timeline](http://www.usaco.org/index.php?page=viewproblem2&cpid=1017)
- [Milking Order](http://www.usaco.org/index.php?page=viewproblem2&cpid=838)
- Other
- [Minimal Labels](http://codeforces.com/contest/825/problem/E) [](53)
- [Quantum](https://open.kattis.com/contests/acpc17open/problems/quantumsuperposition) [](84)

View file

@ -1,47 +0,0 @@
---
slug: /gold/introductory-number-theory
title: "Introductory Number Theory"
author: Unknown
order: 7
---
<div class="syllabus-only">
Description: Todo
</div>
<!-- END DESCRIPTION -->
See 13 of https://www.overleaf.com/project/5e73f65cde1d010001224d8a
- Prime factorization, GCD, LCM
- Modular Arithmetic
Also see here: https://codeforces.com/blog/entry/77137
# Binary Exponentiation
<!-- END DESCRIPTION -->
- Tutorial
- CPH (23, Matrices)
- Problems
- [Currencies](https://www.hackerrank.com/contests/gs-codesprint/challenges/currencies) [](107)
COWBASIC
(old)
### 4
* Eratosthenes' Sieve
* Tutorial
* CPH (21, NT)
### 5
* Modular Arithmetic
* Modular Inverse
* Chinese Remainder Theorem
* Euler's Theorem, Phi Function
* Discrete Logarithm

View file

@ -1,16 +1,17 @@
---
slug: /gold/bfs
id: bfs
title: "Breadth First Search"
author: Benjamin Qi
order: 2
prerequisites:
-
- Silver - Depth First Search
---
<module-excerpt>
Compute shortest paths where all edge weights are 1.
<!-- END DESCRIPTION -->
</module-excerpt>
- [CSES Message Route](https://cses.fi/problemset/task/1667)
@ -24,9 +25,12 @@ Compute shortest paths where all edge weights are 1.
### Problems
- [CSAcademy BFS-DFS](https://csacademy.com/contest/round-41/task/bfs-dfs/) [](50)
- [Cow Navigation](http://www.usaco.org/index.php?page=viewproblem2&cpid=695)
- [Dream](http://www.usaco.org/index.php?page=viewproblem2&cpid=575)
- bad problem ...
- [Lasers](http://www.usaco.org/index.php?page=viewproblem2&cpid=671)
- [Monsters](https://cses.fi/problemset/task/1194)
- USACO
- [Monsters](https://cses.fi/problemset/task/1194)
- [Cow Navigation](http://www.usaco.org/index.php?page=viewproblem2&cpid=695)
- [Dream](http://www.usaco.org/index.php?page=viewproblem2&cpid=575)
- bad problem ...
- [Lasers](http://www.usaco.org/index.php?page=viewproblem2&cpid=671)
- [Visit FJ](http://www.usaco.org/index.php?page=viewproblem2&cpid=717)
- Other
- [CSAcademy BFS-DFS](https://csacademy.com/contest/round-41/task/bfs-dfs/) [](50)

View file

@ -1,19 +1,20 @@
---
slug: /gold/bit
id: bit
title: "Binary Indexed Trees"
author: Benjamin Qi
order: 6
prerequisites:
-
- Silver - Prefix Sums
---
<module-excerpt>
A **Binary Indexed Tree** allows you to perform the following tasks in $O(\log N)$ time each on an array of size $N$:
- Update the element at a single position (point).
- Querying the sum of a prefix of the array.
- Query the sum of a prefix of the array.
<!-- END DESCRIPTION -->
</module-excerpt>
## Binary Indexed Tree

123
content/5_Gold/DP.md Normal file
View file

@ -0,0 +1,123 @@
---
id: dp
title: "Introduction to Dynamic Programming"
author: Michael Cao
prerequisites:
-
- Recursion
-
- Silver - Prefix Sums
---
<module-excerpt>
**Dynamic Programming (DP)** is a very important concept which emerges in the Gold division and extends to the IOI.
</module-excerpt>
[[info | Contest Tip]]
| Usually at least one problem from every gold division contest involves some sort of DP.
## Tutorial
The following tutorials serve as an introduction into the mindset of DP.
- CPH 7
- great introduction that covers most classical problems
- [Topcoder DP](https://www.topcoder.com/community/competitive-programming/tutorials/dynamic-programming-from-novice-to-advanced/)
- great for all skill levels
- [CPC.6](https://github.com/SuprDewd/T-414-AFLV/tree/master/06_dynamic_programming)
- examples with nonclassical problems
- [HackerRank DP](https://www.hackerrank.com/topics/dynamic-programming)
- also covers many classical problems
Practice makes perfect. Start by doing some classical problems (try at least one of each), as these are **must know** DP problems. Each topic starts with direct applications of the classical problems, and then some interesting variations and USACO problems which utilize the ideas. Solutions for most problems (excluding USACO) can be found on Chapter 7 of CPH.
## General
- [**Atcoder DP Contest**](https://atcoder.jp/contests/dp/tasks)
- very good!
- [CSES DP Section](https://cses.fi/problemset/list/)
- also very good!
- [Codeforces DP Problem List](http://codeforces.com/blog/entry/325)
The following USACO problems don't fall into any of the categories below. Arranged roughly in order of difficulty.
[[info | Pro Tip]]
| Sometimes it's a good idea to write a slower polynomial-time solution and then optimize it to the desired complexity (say, write $O(N^2)$ first and then speed it up to $O(N)$).
- [Hoof Paper Scissors](http://www.usaco.org/index.php?page=viewproblem2&cpid=694)
- `dp[first i games][# changes][last gesture] -> max games won`
- [Time is Mooney](http://www.usaco.org/index.php?page=viewproblem2&cpid=993)
- `dp[time][city] -> money`
- [Teamwork](http://usaco.org/index.php?page=viewproblem2&cpid=863)
- $O(NK^2)\to O(NK)$
- [Snakes](http://www.usaco.org/index.php?page=viewproblem2&cpid=945)
- `dp[first m groups][k changes] -> total sum of net sizes`
- $O(N^4)\to O(N^3)$
- [Circular Barn Revisited](http://www.usaco.org/index.php?page=viewproblem2&cpid=622)
- can brute force make your DP easier? (yes)
- [Taming the Herd](http://www.usaco.org/index.php?page=viewproblem2&cpid=815)
- `dp[consider first i entries only][last breakout in first i occurs at j][k breakouts among first i entries] -> # changes`
- [Mortal Cowmbat](http://usaco.org/index.php?page=viewproblem2&cpid=971)
- Use Floyd-Warshall, Prefix Sums
- `dp[first i letters form valid combo][last letter] -> time`
- [Stamp Painting](http://www.usaco.org/index.php?page=viewproblem2&cpid=791)
- must be $K$ consecutive with same color
- $O(NK)\to O(N)$
## Bounded and Unbounded Knapsack
- Classic
- [Unbounded Knapsack](https://www.hackerrank.com/challenges/unbounded-knapsack/problem)
- [Unordered Coin Change](https://cses.fi/problemset/task/1635)
- [Ordered Coin Change](https://cses.fi/problemset/task/1636)
- [Minimum Coins](https://cses.fi/problemset/task/1634)
- [0/1](https://www.hackerrank.com/contests/srin-aadc03/challenges/classic-01-knapsack/problem)
- [Large Capacity + Small Values](https://atcoder.jp/contests/dp/tasks/dp_e)
- Reconsider the state.
- USACO Gold
- [Fruit Feast](http://www.usaco.org/index.php?page=viewproblem2&cpid=574)
- `dp[fullness] = whether you can achieve this fullness`
- [Talent Show](http://www.usaco.org/index.php?page=viewproblem2&cpid=839)
- binary search + knapsack on weight
- CF
- [Round Subset](http://codeforces.com/contest/837/problem/D) [](59)
- [Fire](http://codeforces.com/contest/864/problem/E) [](59)
## Paths on Grid (& Related)
- Classic
- Longest Common Subsequence
- [Standard](https://leetcode.com/problems/longest-common-subsequence/)
- Edit Distance
- [Standard](https://www.hackerrank.com/contests/cse-830-homework-3/challenges/edit-distance)
- Paths on a Grid
- [Count Paths](https://atcoder.jp/contests/dp/tasks/dp_h)
- USACO
- [Gold - Cow Checklist](http://www.usaco.org/index.php?page=viewproblem2&cpid=670)
- `dp[visited i Hs][visited j Gs][last cow visited] -> min energy`
- [Gold - Radio Contact](http://www.usaco.org/index.php?page=viewproblem2&cpid=598)
- similar to above
- [Gold - Why Did The Cow Cross the Road II](http://www.usaco.org/index.php?page=viewproblem2&cpid=718)
- variation on LCS
- [Old Silver - Landscaping](http://www.usaco.org/index.php?page=viewproblem2&cpid=126)
- Although the problem looks different, this is actually a direct application of edit distance.
- [Old Gold - Palindromic Paths](http://www.usaco.org/index.php?page=viewproblem2&cpid=553)
- What are some properties of the answer?
- Other
- [TC Interleaving Parentheses](https://community.topcoder.com/stat?c=problem_statement&pm=14635&rd=16933)
- [K-Ordered LCS](https://www.hackerearth.com/problem/algorithm/mancunian-and-k-ordered-lcs-e6a4b8c6/)
- [CSA Wrong Brackets](https://csacademy.com/contest/round-51/task/wrong-brackets/) [](69)
## Longest Increasing Subsequence
(add?)
- [LIS in Quadratic Time](https://leetcode.com/problems/longest-increasing-subsequence/)
- Try to improve to $O(N\log N)$: [Solution](https://cp-algorithms.com/sequences/longest_increasing_subsequence.html).
- [Cowjog](http://www.usaco.org/index.php?page=viewproblem2&cpid=489)
- Not so easy to see, but direct application of LIS.
- [Sort It Out (USACO Platinum)](http://www.usaco.org/index.php?page=viewproblem2&cpid=865)
- Challenging!

View file

@ -1,8 +1,7 @@
---
slug: /gold/dp-trees
id: dp-trees
title: "Dynamic Programming on Trees"
author: Michael Cao
order: 8
prerequisites:
-
- Silver - Depth First Search
@ -10,7 +9,9 @@ prerequisites:
- Gold - Introduction to Dynamic Programming
---
<!-- END DESCRIPTION -->
<module-excerpt>
</module-excerpt>
## Tutorial
@ -19,8 +20,8 @@ prerequisites:
## Problems
[[info | Pro Tip]]
| Don't just dive into trying to figure out a DP state and transitions -- make some observations if you don't see any obvious DP solution!
[[info | Pro Tip]]
| Don't just dive into trying to figure out a DP state and transitions -- make some observations if you don't see any obvious DP solution!
* [Subtree](https://atcoder.jp/contests/dp/tasks/dp_v)
* [Independent Set](https://atcoder.jp/contests/dp/tasks/dp_p)

92
content/5_Gold/DS.md Normal file
View file

@ -0,0 +1,92 @@
---
id: data-structures-gold
title: "Data Structures (Gold)"
author: Michael Cao
prerequisites:
-
- Bronze - Data Structures
- (?) Silver - Data Structures
---
<module-excerpt>
More advanced applications of data structures introduced in earlier divisions.
</module-excerpt>
# Monotonic Stack
Consider the following problem:
> Given an array, $a$, of $N (1 \le N \le 10^5)$ integers, for every index $i$, find the rightmost index $j$ such that $j < i$ and $a_i > a_j$.
To solve this problem, let's store a stack of pairs of `<value, index>` and iterate over the array from left to right. For some index $i$, we will compute $ans_i$, the rightmost index for $i$, as follows:
- Keep popping the top element off the stack as long as $value \ge a_i$. This is because we know that the pair containing $value$ will never be the solution to any index $j > i$, since $a_i$ is less than or equal to than $value$ and has an index further to the right.
- If $value < a_i$, set $ans[i]$ to $index$, because a stack stores the most recently added values first (or in this case, the rightmost ones), $index$ will contain the rightmost value which is less than $a_i$. Then, pop the top element off the stack, because $index$ can't be the solution for two elements.
The stack we used is called a "monotonic stack" because we keep popping off the top element of the stack which maintains it's monotonicity (the same property needed for algorithms like binary search) because the elements in the stack are increasing.
## Further Reading
- "Nearest Smallest Element" from CPH 8
- [CP Algorithms (Min Stack)](https://cp-algorithms.com/data_structures/stack_queue_modification.html)
- [Medium](https://medium.com/@vishnuvardhan623/monotonic-stack-e9dcc4fa8c3e)
## Problems
- [Concurrently Balanced Strings (Old Gold)](http://www.usaco.org/index.php?page=viewproblem2&cpid=194)
- [Max Histogram Area (Leetcode)](https://leetcode.com/problems/largest-rectangle-in-histogram/)
(add more once codeforces comes up)
# Sliding Window
Let's envision a sliding window (or constant size subarray) of size $K$ moving left to right along an array, $a$. For each position of the window, we want to compute some information.
Let's store a `std::set` of integers representing the integers inside the window. If the window currently spans the range $i \dots j$, we observe that moving the range forward to $i+1 \dots j+1$ only removes $a_i$ and adds $a_{j+1}$ to the window. We can support these two operations and query for the minimum/maximum in the set in $O(\log N)$.
To compute the sum in the range, instead of using a set, we can store a variable $s$ representing the sum. As we move the window forward, we update $s$ by performing the operations $s$ -= $a_i$ and $s$ += $a_{j+1}$.
## Further Reading
- "Sliding Window" from CPH 8
- Read [this article]([https://cp-algorithms.com/data_structures/stack_queue_modification.html](https://cp-algorithms.com/data_structures/stack_queue_modification.html)) to learn about the "min queue" that CPH describes.
- [Medium]([https://levelup.gitconnected.com/an-introduction-to-sliding-window-algorithms-5533c4fe1cc7](https://levelup.gitconnected.com/an-introduction-to-sliding-window-algorithms-5533c4fe1cc7))
- [G4G]([https://www.geeksforgeeks.org/window-sliding-technique/](https://www.geeksforgeeks.org/window-sliding-technique/))
## Problems
- [Haybale Feast (Gold)](http://usaco.org/index.php?page=viewproblem2&cpid=767)
- Direct application of sliding window.
- [Train Tracking 2 (Plat)]([http://www.usaco.org/current/data/sol_train_platinum_open18.html](http://www.usaco.org/current/data/sol_train_platinum_open18.html))
- Not really sliding window but mentions it.
- Extremely difficult.
(add more once codeforces comes up)
# Merging Sets
Let's consider a tree, rooted at node $1$, where each node has a color (see [CSES Distinct Colors](https://cses.fi/problemset/task/1139)).
For each node, let's store a set containing only that node, and we want to merge the sets in the nodes subtree together such that each node has a set consisting of all colors in the nodes subtree. Doing this allows us to solve a variety of problems, such as query the number of distinct colors in each subtree. Doing this naively, however, yields a runtime complexity of $O(N^2)$.
However, with just a few lines of code, we can significantly speed this up.
```cpp
if(a.size() < b.size()){ //for two sets a and b
swap(a,b);
}
```
In other words, by merging the smaller set into the larger one, the runtime complexity becomes $O(N\log N).$
<details>
<summary> Proof </summary>
When merging two sets, you move from the smaller set to the larger set. If the size of the smaller set is $X$, then the size of the resulting set is at least $2X$. Thus, an element that has been moved $Y$ times will be in a set of size $2^Y$, and since the maximum size of a set is $N$ (the root), each element will be moved at most $O(\log N$) times leading to a total complexity of $O(N\log N)$.
</details>
Additionally, a set doesn't have to be an `std::set`. Many data structures can be merged, such as `std::map` or even adjacency lists.
[[info | Challenge]]
| Prove that if you instead merge sets that have size equal to the depths of the subtrees, then small to large merging does $O(N)$ insert calls.
## Further Reading
- "Merging Data Structures" from CPH 18
## Problems
- [Favorite Colors (USACO Gold)](http://www.usaco.org/index.php?page=viewproblem2&cpid=1042)
- Merge Adjacency Lists

107
content/5_Gold/Intro_NT.md Normal file
View file

@ -0,0 +1,107 @@
---
id: intro-nt
title: "Introductory Number Theory"
author: Darren Yao
---
<module-excerpt>
- Prime Factorization
- GCD & LCM
- Modular Arithmetic
</module-excerpt>
## Additional Resources
- CSES 21.1, 21.2
- [CF CodeNCode](https://codeforces.com/blog/entry/77137)
## Prime Factorization
A number $a$ is called a **divisor** or a **factor** of a number $b$ if $b$ is divisible by $a$, which means that there exists some integer $k$ such that $b = ka$. Conventionally, $1$ and $n$ are considered divisors of $n$. A number $n > 1$ is **prime** if its only divisors are $1$ and $n$. Numbers greater than \(1\) that are not prime are **composite**.
Every number has a unique **prime factorization**: a way of decomposing it into a product of primes, as follows:
\[ n = {p_1}^{a_1} {p_2}^{a_2} \cdots {p_k}^{a_k} \]
where the $p_i$ are distinct primes and the $a_i$ are positive integers.
Now, we will discuss how to find the prime factorization of an integer.
(pseudocode)
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$.
(table)
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
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}
a & b = 0 \\
\gcd(b, a \bmod b) & b \neq 0 \\
\end{cases}
$$
This algorithm is very easy to implement using a recursive function in Java, as follows:
```java
public int gcd(int a, int b){
if(b == 0) return a;
return gcd(b, a % b);
}
```
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)$.
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)}$$
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,
$$\gcd(a_1, a_2, a_3, a_4) = \gcd(a_1, \gcd(a_2, \gcd(a_3, a_4)))$$
## 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:
```
todo no support for gather
$$
\begin{gather*}
(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^b \bmod {m} = (a \bmod m)^b \bmod m
\end{gather*}
$$
```
### Modular Exponentiation
?
### Modular Inverse
Under a prime moduli, division exists.
## Problems
- USACO
- Both are also Knapsack DP problems.
- [Cow Poetry](http://usaco.org/index.php?page=viewproblem2&cpid=897)
- First consider the case where there are only two lines with the same class.
- Requires fast modular exponentiation for full credit.
- [Exercise](http://www.usaco.org/index.php?page=viewproblem2&cpid=1043)
- Prime factorization
- Other
- [CF VK Cup 2012 Wildcard Round 1 C](https://codeforces.com/problemset/problem/162/C)

View file

@ -1,16 +1,17 @@
---
slug: /gold/mst
id: mst
title: "Minimum Spanning Trees"
author: Benjamin Qi
order: 5
prerequisites:
-
- Gold - Shortest Paths
---
Disjoint Set Union and Minimum Spanning Trees
<module-excerpt>
<!-- END DESCRIPTION -->
**Disjoint Set Union** and **Minimum Spanning Trees**
</module-excerpt>
## Standard

View file

@ -1,18 +1,19 @@
---
slug: /gold/sp
id: sp
title: "Shortest Paths"
author: Benjamin Qi
order: 4
prerequisites:
-
- Gold - Breadth First Search
---
- Shortest Path Without Negative Edge Weights
<module-excerpt>
- Shortest Path Without Negative Edge Weights
- Shortest Path With Negative Edge Weights
- All Pairs Shortest Path
<!-- END DESCRIPTION -->
</module-excerpt>
## Non-Negative Edge Weights

View file

@ -0,0 +1,46 @@
---
id: toposort
title: "Topological Sort"
author: Benjamin Qi, Michael Cao
prerequisites:
-
- Gold - Breadth First Search
---
To review, a **directed** graph consists of edges that can only be traversed in one direction. Additionally, a **acyclic** graph defines a graph which does not contain cycles, meaning you are unable to traverse across one or more edges and return to the node you started on. Putting these definitions together, a **directed acyclic** graph, sometimes abbreviated as DAG, is a graph which has edges which can only be traversed in one direction and does not contain cycles.
A [topological sort](https://en.wikipedia.org/wiki/Topological_sorting) of a directed acyclic graph is a linear ordering of its vertices such that for every directed edge $u\to v$ from vertex $u$ to vertex $v$, $u$ comes before $v$ in the ordering.
## Tutorial
- CPH 16.1, 16.2
- DFS
- [cp-algorithms](https://cp-algorithms.com/graph/topological-sort.html)
- DFS
- [CSAcademy](https://csacademy.com/lesson/topological_sorting)
- both BFS, DFS
## Dynamic Programming
One useful property of directed acyclic graphs is, as the name suggests, that there exists no cycles. If we consider each node in the graph as a state, we can perform dynamic programming on the graph if we process the states in an order that guarantees for every edge, $u\to v$ that $u$ is processed before $v$. Fortunately, this is the exact definition of a topological sort!
Let's consider a classical problem (see Longest Flight Route) where we must find the longest path in a Directed Acyclic Graph. Let `dp[curr] = longest path ending at the node curr`. Then, if we process states in topological order, the transition is relatively straightforward: `dp[curr] = max of all dp[prev] where prev represents a node with an edge going into the current node` (word better?). To reiterate, since the states a processed in topological order, we can guarantee that all possible `dp[prev]` are computed before we compute `dp[curr]`.
However, not all problems clearly give you directed acyclic graphs (see [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.
## Example Problems
- [CSES Course Schedule](https://cses.fi/problemset/task/1679)
- [CSES Longest Flight Route](https://cses.fi/problemset/task/1680)
- [CSES Game Routes](https://cses.fi/problemset/task/1681)
## Problems
- USACO Gold
- [Timeline](http://www.usaco.org/index.php?page=viewproblem2&cpid=1017)
- Dynamic Programming on DAG.
- [Milking Order](http://www.usaco.org/index.php?page=viewproblem2&cpid=838)
- Binary search and check if a valid topological sort exists. Consider [Khan's Algorithm](https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm) for topological sorting.
- Other
- [Minimal Labels](http://codeforces.com/contest/825/problem/E) [](53)
- [Quantum](https://open.kattis.com/contests/acpc17open/problems/quantumsuperposition) [](84)

View file

@ -1,20 +1,21 @@
---
slug: /plat/1DRQ
id: 1DRQ
title: "1D Range Queries"
author: Benjamin Qi
order: 2
prerequisites:
-
- Gold - Binary Indexed Trees
---
<module-excerpt>
General range queries for associative operations, including segment tree.
<!-- END DESCRIPTION -->
</module-excerpt>
## Static Range 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]$ in $O(1)$ time each with $O(N\log N)$ time preprocessing, where $\ominus$ denotes any associative operation. In the case when $\ominus$ denotes `min`, preprocessing can be done in $O(1)$ time.
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]$ in $O(1)$ time each with $O(N\log N)$ time preprocessing, where $\ominus$ denotes any associative operation. In the case when $\ominus$ denotes `min`, preprocessing can be done in $O(N)$ time.
### Tutorial
@ -41,6 +42,7 @@ See my implementation [here](https://github.com/bqi343/USACO/blob/master/Impleme
- [DMOJ Continued Fractions](https://dmoj.ca/problem/dmopc19c7p4)
- [USACO Plat - NonDec](http://www.usaco.org/index.php?page=viewproblem2&cpid=997)
- [JOI Secret](https://oj.uz/problem/view/JOI14_secret)
## Segment Tree

View file

@ -1,16 +1,17 @@
---
slug: /plat/2DRQ
id: 2DRQ
title: "2D Range Queries"
author: Benjamin Qi
order: 3
prerequisites:
-
- Platinum - 1D Range Queries
---
<module-excerpt>
Extending Range Queries to 2D (and beyond).
<!-- END DESCRIPTION -->
</module-excerpt>
See [my implementations](https://github.com/bqi343/USACO/tree/master/Implementations/content/data-structures/2D%20Range%20Queries%20(15.2)).

View file

@ -1,20 +1,21 @@
---
slug: /plat/bitset
title: "Bitset"
id: bitsets
title: "Bitsets"
author: Benjamin Qi
order: 7
---
Three examples of how bitset leads to some unintended solutions on recent USACO problems.
<module-excerpt>
<!-- END DESCRIPTION -->
Three examples of how **bitsets** lead to some unintended solutions on recent USACO problems.
</module-excerpt>
## Tutorial
tl;dr some operations are 32x-64x faster compared to a boolean array
tl;dr some operations are 32x-64x faster compared to a boolean array.
- [Cpp Reference](http://www.cplusplus.com/reference/bitset/bitset/)
- [Errichto Pt 2](https://codeforces.com/blog/entry/73558)
- [C++ Reference](http://www.cplusplus.com/reference/bitset/bitset/)
- [Errichto Bitwise Operations Pt 2](https://codeforces.com/blog/entry/73558)
## Applications

View file

@ -1,8 +1,7 @@
---
slug: /plat/dp-bitmasks
id: dp-bitmasks
title: "Dynamic Programming on Bitmasks"
author: Michael Cao
order: 10
prerequisites:
-
- Bit Operations
@ -10,7 +9,9 @@ prerequisites:
- Gold - Introduction to Dynamic Programming
---
<!-- END DESCRIPTION -->
<module-excerpt>
</module-excerpt>
Note: Has not appeared on recent USACO.

View file

@ -1,14 +1,15 @@
---
slug: /plat/dp-ranges
id: dp-ranges
title: "Dynamic Programming on Ranges"
author: Michael Cao
order: 11
prerequisites:
-
- Gold - Introduction to Dynamic Programming
---
<!-- END DESCRIPTION -->
<module-excerpt>
</module-excerpt>
## Problems

View file

@ -1,8 +1,7 @@
---
slug: /plat/fracture
id: fracture
title: "Fracturing Search"
author: Benjamin Qi
order: 8
prerequisites:
-
- Gold - Minimum Spanning Tree
@ -10,9 +9,11 @@ prerequisites:
- some familiarity with "Robotic Cow Herd" analysis
---
<module-excerpt>
A simple solution to [Robotic Cow Herd](http://www.usaco.org/index.php?page=viewproblem2&cpid=674) that generalizes.
<!-- END DESCRIPTION -->
</module-excerpt>
## General Outline
@ -68,9 +69,7 @@ for each $i\in [1,N-1]$. Every spanning tree other than the root is contained wi
Overall, the runtime is $O(NMK\alpha(N))$ for storing the information about each spanning tree and $O(NK\log (NK))$ for maintaing the priority queue of objects so that we can extract the minimum. Note that with the second approach mentioned in the first section the running time would instead be $O(NMK\alpha(N)\log ans)$, which may be too slow.
<details>
<summary>My Solution</summary>
<spoiler title="My Solution">
```cpp
#include <bits/stdc++.h>
@ -127,7 +126,7 @@ int main() {
}
```
</details>
</spoiler>
## [USACO Robotic Cow Herd](http://www.usaco.org/index.php?page=viewproblem2&cpid=674)
@ -144,9 +143,7 @@ Importantly, we should then sort the locations by their respective second-minimu
Binary search on the cost $c$ of the $K$-th robot. If we can compute the costs of all robots with cost at most $c$ or say that there are more than $K$ in $O(K)$ time, then we can solve this problem in $O(N\log N+K\log \max(c))$ time (similar to "Approach 2" above). This is the approach that the first analysis solution takes, although it includes an extra $\log N$ factor due to `upper_bound`. I have removed this in my solution below.
<details>
<summary>My Solution 1</summary>
<spoiler title="My Solution 1">
```cpp
#include <bits/stdc++.h>
@ -205,7 +202,7 @@ int main() {
}
```
</details>
</spoiler>
## Approach 2
@ -241,9 +238,7 @@ None of these options can result in a robot of lower cost. In general, suppose t
Since there exists exactly one way to get from the cheapest robot to every possible robot, we can just use a priority queue.
<details>
<summary>My Solution 2</summary>
<spoiler title="My Solution 2">
```cpp
#include <bits/stdc++.h>
@ -291,7 +286,7 @@ int main() {
}
```
</details>
</spoiler>
## Other Problems

View file

@ -1,13 +1,14 @@
---
slug: /plat/geo
id: geo
title: "Geometry"
author: Benjamin Qi
order: 4
---
<module-excerpt>
Geometry primitives and convex hull.
<!-- END DESCRIPTION -->
</module-excerpt>
## Primitives

View file

@ -1,18 +1,19 @@
---
slug: /plat/graphs
id: graphs
title: "Graphs"
author: Benjamin Qi
order: 5
prerequisites:
-
- Gold - Topological Sort
---
- Eulerian Tours
<module-excerpt>
- Eulerian Tours
- SCCs
- BCCs
<!-- END DESCRIPTION -->
</module-excerpt>
Note: all except the third have not appeared on a recent USACO contest.

View file

@ -1,13 +1,14 @@
---
slug: /plat/oly
id: oly
title: "Olympiads"
author: Benjamin Qi
order: 0
---
<module-excerpt>
Once you've reached Platinum, it may be helpful to practice with problems from other (inter)national olympiads.
<!-- END DESCRIPTION -->
</module-excerpt>
> Hello, Which online judge should I practice more to do well in **IOI** ?
> the closest OJ for IOI style?
@ -58,11 +59,11 @@ See [here](https://ioinformatics.org/page/members/7) for additional links. The [
* Misc
* [List of 2017 IOI Participants](http://weaselcrow.com/pro/cf/ioi2017/)
* [IOI 2018 Syllabus](https://people.ksp.sk/~misof/ioi-syllabus/ioi-syllabus.pdf)
* [Baltic OI](http://www.boi2017.org/)
* [CEOI](http://ceoi.inf.elte.hu/)
* [Baltic](http://www.boi2017.org/) (BOI)
* [Central European](http://ceoi.inf.elte.hu/) (CEOI)
* submit BOI / CEOI at [CSES](https://cses.fi/)
* [Balkan OI](http://boi2018.ro/home)
* [IZhO](https://oj.uz/problems/source/24)
* [APIO](http://apio-olympiad.org/)
* [IOIT](http://ioit.altervista.org/2018-teams-and-contests-.html)
* [Balkan](http://boi2018.ro/home)
* [International Zhautykov](https://oj.uz/problems/source/24) (IZhO)
* [Asia-Pacific](http://apio-olympiad.org/) (APIO)
* [International Informatics Olympiad in Teams](http://ioit.altervista.org/2018-teams-and-contests-.html) (IOIT)
* [InfO(1) cup](http://info1cup.com/)

View file

@ -1,16 +1,17 @@
---
slug: /plat/slope
id: slope
title: "Slope Trick"
author: Benjamin Qi
order: 9
prerequisites:
-
- some familiarity with at least one of the two tutorials mentioned in this module
---
<module-excerpt>
**Slope trick** refers to manipulating piecewise linear convex functions. Includes a simple solution to [Landscaping](http://www.usaco.org/index.php?page=viewproblem2&cpid=650).
<!-- END DESCRIPTION -->
</module-excerpt>
## Tutorials
@ -44,9 +45,7 @@ We'll process the shares in order. Suppose that on the current day shares are wo
The implementation is quite simple; maintain a priority queue that allows you to pop the minimum element.
<details>
<summary>My Solution</summary>
<spoiler title="My Solution">
```cpp
#include <bits/stdc++.h>
@ -67,7 +66,7 @@ int main() {
cout << ans << "\n";
}
```
</details>
</spoiler>
## [Potatoes](https://oj.uz/problem/view/LMIO19_bulves)
@ -82,9 +81,7 @@ As before, this DP is concave up for a fixed $i$! Given a piecewise linear funct
Again, these can be done with a priority queue in $O(N\log N)$ time!
<details>
<summary>My Solution</summary>
<spoiler title="My Solution">
```cpp
#include <bits/stdc++.h>
@ -118,7 +115,7 @@ int main() {
}
```
</details>
</spoiler>
## [Landscaping](http://www.usaco.org/index.php?page=viewproblem2&cpid=650)
@ -142,9 +139,7 @@ If we maintain separate deques for $dif$ depending on whether $j\ge 0$ or $j<0$
Bonus: Solve this problem when $\sum A_i+\sum B_i$ is not so small.
<details>
<summary>My Solution</summary>
<spoiler title="My Solution">
```cpp
#include <bits/stdc++.h>
@ -183,7 +178,7 @@ int main() {
cout << ans << "\n";
}
```
</details>
</spoiler>
## Problems

View file

@ -1,14 +1,15 @@
---
slug: /plat/hashing
id: strings
title: "Strings"
author: Benjamin Qi
order: 6
prerequisites:
-
- Silver - Depth First Search
---
- Tries
<module-excerpt>
- Tries
- Hashing
- Z
- KMP
@ -16,7 +17,7 @@ prerequisites:
- Aho-Corasick
- Suffix Array
<!-- END DESCRIPTION -->
</module-excerpt>
Note: String algorithms do not appear very frequently. Hashing has appeared on gold (rarely).

View file

@ -1,16 +1,17 @@
---
slug: /plat/trees
id: trees
title: "Trees"
author: Benjamin Qi
order: 1
prerequisites:
-
- Silver - Depth First Search
---
<module-excerpt>
Lowest Common Ancestor and other tree topics.
<!-- END DESCRIPTION -->
</module-excerpt>
## Tree Diameter
@ -35,19 +36,21 @@ Lowest Common Ancestor and other tree topics.
USACO:
- [USACO Plat Max Flow](http://www.usaco.org/index.php?page=viewproblem2&cpid=576)
- [USACO Gold Milk Visits](http://www.usaco.org/index.php?page=viewproblem2&cpid=970)
- [USACO Gold Cow Land](http://www.usaco.org/index.php?page=viewproblem2&cpid=921)
- LCA + BIT
- [USACO Plat Promote](http://www.usaco.org/index.php?page=viewproblem2&cpid=696)
- Subtree + BIT
- [USACO Plat Disrupt](http://www.usaco.org/index.php?page=viewproblem2&cpid=842)
- HLD is possible, but just do binary jumps
- [USACO Plat Tree Boxes](http://www.usaco.org/index.php?page=viewproblem2&cpid=948)
- interactive!!
- [USACO Plat Gathering](http://www.usaco.org/index.php?page=viewproblem2&cpid=866)
- [USACO Plat Exercise](http://www.usaco.org/index.php?page=viewproblem2&cpid=901)
- tricky
- Gold
- [USACO Gold Milk Visits](http://www.usaco.org/index.php?page=viewproblem2&cpid=970)
- [USACO Gold Cow Land](http://www.usaco.org/index.php?page=viewproblem2&cpid=921)
- LCA + BIT
- Plat
- [Max Flow](http://www.usaco.org/index.php?page=viewproblem2&cpid=576)
- [Promote](http://www.usaco.org/index.php?page=viewproblem2&cpid=696)
- Subtree + BIT
- [Disrupt](http://www.usaco.org/index.php?page=viewproblem2&cpid=842)
- HLD is possible, but just do binary jumps
- [Tree Boxes](http://www.usaco.org/index.php?page=viewproblem2&cpid=948)
- interactive!!
- [Gathering](http://www.usaco.org/index.php?page=viewproblem2&cpid=866)
- [Exercise](http://www.usaco.org/index.php?page=viewproblem2&cpid=901)
- tricky
Other:
@ -63,6 +66,7 @@ Other:
### Problems
- [Ciel the Commander](https://codeforces.com/problemset/problem/321/C)
- [USACO Plat - At Large](http://www.usaco.org/index.php?page=viewproblem2&cpid=793)
- very tricky
- [DMOJ Bob Equilibrium](https://dmoj.ca/problem/dmopc19c7p6)
@ -82,5 +86,6 @@ Other:
??
## Small to Large (Offline)
??
Sample codes: [DSU on Tree code](https://codeforces.com/blog/entry/44351), [explanation of code](https://codeforces.com/blog/entry/67696)
- USACO Disrupt again!
- [Lomsat gelral](https://codeforces.com/contest/600/problem/E)

View file

@ -1,337 +0,0 @@
---
slug: ?
title: Containers
author: Nathan Wang
order: 2
---
- todo write table of contents
<!-- END DESCRIPTION -->
// RIP java...
## Stacks
A Last-In-First-Out (LIFO) Data Structure.
- Reference: http://www.cplusplus.com/reference/stack/stack/
- Complexity: `O(1)`
Imagine a stack of cards. When we “push” a card into the stack, we put the card on the top of the stack. Then when we “pop” the top of the stack, we remove the topmost card of the stack.
Important Functions:
- `stack.push(element)`: inserts an element to the top of the stack.
- `stack.top()`: returns the topmost element of the stack (the element that was most recently added). Note that this does not remove the element from the stack.
- `stack.pop()`: removes the topmost element from the stack.
- `stack.empty()`: returns true of the stack is empty.
- `stack.size()`: returns the size of the stack.
Example:
```cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
stack<int> s;
s.push(1);
s.push(2);
s.push(3);
while (!s.empty()) {
int next = s.top(); s.pop();
cout << next << endl;
}
}
/* Output:
* 1
* 2
* 3
*/
```
**Basic Problems**:
- UVa 00514 - Rails
- UVa 00732 - Anagram by Stack
- UVa 01062 - Containers
## Queues
A First-In-First-Out (FIFO) Data Structure.
- Reference: http://www.cplusplus.com/reference/queue/queue/
- Complexity: `O(1)`
Imagine a line of people (a queue of people). When we push a person into the line, we append the person to the end of the line. When we pop a person from the line, we get the front-most person that has been waiting in line the longest.
Important Functions:
- `queue.push(element)`: Adds the element to the end of the queue.
- `queue.pop()`: Removes the front-most element.
- `queue.front()`: Returns the front-most element.
- `queue.size()`: Returns the size of the queue.
- `queue.empty()`: Tests whether or not the queue is empty.
Example:
```cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
queue<int> q;
q.push(1);
q.push(2);
q.push(3);
while (!q.empty()) {
int next = q.front(); q.pop();
cout << next << endl;
}
}
/* Output:
* 1
* 2
* 3
*/
```
## Deques
A double-ended queue (pronounced “deck”) that supports insertion and retrieval from two ends. Not very common in Silver.
- Reference: http://www.cplusplus.com/reference/deque/deque/
- Complexity: `O(1)`
Important Functions:
- `deque.empty()`: Test whether container is empty
- `deque.size()`: Return size
- `deque.push_back()`: Add element to end
- `deque.push_front()`: Add element to beginning
- `deque.front()`: Access first element
- `deque.back()`: Access last element
- `deque.pop_back()`: Delete last element
- `deque.pop_front()`: Delete first element
- `deque.clear()`: Clear content
Example:
```cpp
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> dq;
dq.push_back(1);
dq.push_front(2);
// dq is [2, 1]
cout << dq.front() << endl; // 2
cout << dq.back() << endl; // 1
}
```
**Queue/Deque Basic Problems**:
- UVa 10172 - The Lonesome Cargo…
- UVa 10901 - Ferry Loading III
- UVa 11034 - Ferry Loading IV
## Priority Queues
A queue that always places the greatest element in front.
- Reference: http://www.cplusplus.com/reference/queue/priority_queue/
- Complexity: `O(log n)` for retrieval, `O(log n)` for insertion
Important Functions:
- `pq.empty()`: Test if container is empty.
- `pq.size()`: Return size of container.
- `pq.top()`: Access top element of container.
- `pq.push(el)`: Insert an element.
- `pq.pop()`: Remove top element.
Example:
```cpp
#include <iostream>
#include <queue>
using namespace std;
int main() {
priority_queue<int> pq;
pq.push(3);
pq.push(2);
pq.push(4);
while (!pq.empty()) {
int next = pq.top(); pq.pop();
cout << next << endl;
}
}
/* Output:
* 4
* 3
* 2
*/
```
## Pair
A structure that holds two values, not necessarily of the same type.
- Reference: http://www.cplusplus.com/reference/utility/pair/pair/
Important Functions:
- `make_pair(a, b)`: Returns a pair with values a, b.
- `pair.first`: The first value of the pair.
- `pair.second`: The second value of the pair.
Example
```cpp
#include <iostream>
using namespace std;
int main() {
pair<string, int> myPair = make_pair("Testing", 123);
cout << myPair.first << " " << myPair.second << endl;
}
/* Output
* Testing 123
*/
```
## Maps
A sorted container that stores key-value pairs.
- Reference: http://www.cplusplus.com/reference/map/map/
- Complexity: `O(log n)` for retrieval. `O(log n)` for insertion.
For unsorted maps, `O(1)` for both (plus hash function)
Note: C++ `map` is sorted. C++ `unordered_map` is unsorted. Java `HashMap` is unsorted. Java `TreeMap` is sorted.
Important Functions:
- `map.empty()`: Test if container is empty
- `map.size()`: Returns size of map
- `map.insert(make_pair(a, b))`: Inserts a key-value pair with key a and value b.
- `map.clear()`: Clears map
- `map[“test”]`: Returns corresponding value with key “test.”
- `map.count(“key”)`: Returns 1 if key exists, and 0 otherwise.
Example
```cpp
#include <iostream>
#include <map>
using namespace std;
int main() {
map<string, int> myMap;
myMap.insert(make_pair("testing", 123));
myMap.insert(make_pair("hello", 456));
cout << myMap["hello"] << endl; // 456
// C++11 onwards
for (auto const& x : myMap) {
std::cout << x.first // key
<< ':'
<< x.second // value
<< std::endl;
}
}
/*
Output
------
456
hello: 456
testing: 123
*/
```
**Basic Problems**:
- UVa 10226 - Hardwood Species
- UVa 11286 - Conformity
- UVa 11572 - Unique Snowflakes
## Sets
A data structure that stores unique elements in a sorted order. The same element will not appear twice in a set.
- Reference: http://www.cplusplus.com/reference/set/set/
- Complexity: `O(log n)` for retrieval, `O(log n)` for insertion
## Multisets
A special set that allows for multiple identical elements.
- Reference: http://www.cplusplus.com/reference/set/multiset/
- Complexity: Same as Set
Important Functions:
- `set.empty()`: Test if container is empty.
- `set.size()`: Return size of set.
- `set.insert(el)`: Inserts the element into the set.
- `set.find(el)`: Returns an iterator to the element.
- `set.count(el)`: Returns the number of items in the set with value “el.”
- `set.erase(val)`: Erases **all instances** of `val` from the (multi)set.
- `set.erase(set.find(val))`: Erases **one instance** of `val` from the multiset.
**Multiset 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`.
Example:
```cpp
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> mySet;
mySet.insert(1);
mySet.insert(3);
cout << mySet.count(1) << " " << mySet.count(2) << endl; // 1 0
multiset<int> myMultiSet;
myMultiSet.insert(1);
myMultiSet.insert(1);
myMultiSet.insert(1);
cout << myMultiSet.count(1) << endl; // 3
myMultiSet.erase(myMultiSet.find(1));
cout << myMultiSet.count(1) << endl; // 2
myMultiSet.erase(1);
cout << myMultiSet.count(1) << endl; // 0, NOT 1!!!!
myMultiSet.insert(2);
myMultiSet.insert(2);
myMultiSet.insert(2);
for (auto x : myMultiSet) {
cout << x << " ";
// outputs 2 2 2
}
}
```
**Set/Multiset Problems**:
- UVa 00978 - Lemmings Battle
- UVa 11136 - Hoax or what
- UVa 11849 - CD
(actually I'm not sure if they're set problems or multiset problems)

View file

@ -1,3 +1,19 @@
---
id: syllabus
title: Syllabus
author: Benjamin Qi
---
<module-excerpt>
(outdated)
Below, we've compiled some of the main topics for each division.
</module-excerpt>
This USACO guide will try to cover all of these topics. Note that USACO contest problems are not limited to just these topics, though _most_ of them should fall into one of the catgories listed below.
# Other Resources
- [USACO -> CPH Topics](https://github.com/bqi343/USACO/blob/master/Contests/USACO%20Links/USACO%20Topics.md)

120
content/ordering.js Normal file
View file

@ -0,0 +1,120 @@
const ModuleOrdering = {
"intro": [
"getting-started",
"prereqs",
"running-cpp",
"data-types",
"io",
"ex-prob",
"practicing",
],
"general": [
"resources",
"contests",
"contest-strategy",
"proposing",
"why-cpp",
"macros",
"debugging",
],
"bronze": [
"rect-geo",
"time-comp",
{
name: "Data Structures",
items: [
"collections",
"containers",
"pairs",
"ds",
]
},
"simulation",
"complete-search",
"intro-graphs",
],
"silver": [
{
name: "Sorting",
items: [
"intro-sorting",
"sorting-custom",
"sorting-cpp",
]
},
"binary-search",
"2P",
"data-structures",
"containers-silver",
"greedy",
"prefix-sums",
{
name: "Graphs",
items: [
"dfs",
"cyc",
]
}
],
"gold": [
{
name: "Graphs",
items: [
"bfs",
"toposort",
"sp",
"mst"
]
},
{
name: "Dynamic Programming",
items: [
"dp",
"dp-trees"
]
},
"data-structures-gold",
"intro-nt",
"bit",
],
"plat": [
"oly",
{
name: "Range Queries",
items: [
"1DRQ",
"2DRQ",
]
},
{
name: "Graphs",
items: [
"trees",
"graphs",
]
},
{
name: "Dynamic Programming",
items: [
"dp-bitmasks",
"dp-ranges",
"slope",
]
},
"geo",
"strings",
"bitsets",
"fracture",
]
};
export default ModuleOrdering;
export const divisions = Object.keys(ModuleOrdering);
export const divisionLabels = {
"intro": "Intro",
"general": "General",
"bronze": "Bronze",
"silver": "Silver",
"gold": "Gold",
"plat": "Platinum",
};

View file

@ -1 +1,58 @@
import "./src/styles/main.css";
import "./src/styles/main.css";
import React from "react";
import { MDXProvider } from "@mdx-js/react";
const SpoilerComponent = ({ children, title }) => {
const [show, setShow] = React.useState(false);
return (
<div className={`border border-gray-200 rounded-md`}>
<p className="p-4 flex items-start"
onClick={e => setShow(!show)} style={{ marginBottom: 0 }}>
{show && <svg className="h-6 w-6 text-gray-500 mr-4" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>}
{!show && <svg className="h-6 w-6 text-gray-500 mr-4" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>}
{title}
</p>
{show && <div className="p-4 pt-0 spoiler-body">{children}</div>}
</div>
);
};
const components = {
wrapper: ({ excerptOnly = false, children }) => {
if (excerptOnly) {
for (let child of children) {
if (child.props.originalType === "module-excerpt") return child;
}
return null;
}
return children;
},
"module-excerpt": (props) => <div {...props} />,
spoiler: SpoilerComponent,
"info-block": ({ children }) => (
<div className="rounded-md bg-blue-50 p-4 info-block mb-4">
<div className="flex">
<div className="flex-shrink-0">
<svg className="h-5 w-5 text-blue-400" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clipRule="evenodd" />
</svg>
</div>
<div className="ml-3">
{children}
</div>
</div>
</div>
),
};
export const wrapRootElement = ({ element }) => (
<MDXProvider
components={components}>
{element}
</MDXProvider>
);

View file

@ -18,14 +18,10 @@ module.exports = {
},
},
{
resolve: `gatsby-transformer-remark`,
resolve: `gatsby-plugin-mdx`,
options: {
commonmark: true,
footnotes: true,
pedantic: false,
gfm: true,
"excerpt_separator": `<!-- END DESCRIPTION -->`,
plugins: [
extensions: [`.mdx`, `.md`],
gatsbyRemarkPlugins: [
`gatsby-remark-autolink-headers`,
{
resolve: "gatsby-remark-custom-blocks",
@ -52,6 +48,9 @@ module.exports = {
},
},
],
plugins: [
`gatsby-remark-autolink-headers`,
]
},
},
{

51
gatsby-node.esm.js Normal file
View file

@ -0,0 +1,51 @@
import ModuleOrdering, { divisions } from "./content/ordering";
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions;
// Generate Module Pages //
const moduleTemplate = require.resolve(`./src/templates/moduleTemplate.js`);
Object.keys(ModuleOrdering).forEach(division => {
const processItem = item => {
if (typeof item === "object") {
// this is a nested module
item.items.forEach(x => processItem(x));
} else {
createPage({
path: `/${division}/${item}`,
component: moduleTemplate,
context: {
// additional data can be passed via context
id: item,
division: division,
},
});
}
};
ModuleOrdering[division].forEach(item => processItem(item));
});
// End Generate Module Pages //
// Generate Syllabus Pages //
const syllabusTemplate = require.resolve(`./src/templates/syllabusTemplate.js`);
divisions.forEach(division => {
createPage({
path: `/${division}`,
component: syllabusTemplate,
context: {
division: division
},
});
});
// End Generate Syllabus Pages //
};
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions;
const typeDefs = `
type MarkdownRemarkFrontmatter implements Node {
prerequisites: [[String]]
}
`;
createTypes(typeDefs)
};

View file

@ -1,94 +1,2 @@
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions;
const moduleTemplate = require.resolve(`./src/templates/moduleTemplate.js`);
const result = await graphql(`
{
allMarkdownRemark {
edges {
node {
frontmatter {
slug
}
}
}
}
}
`);
// Handle errors
if (result.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`);
return;
}
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
if (!node.frontmatter.slug) return;
createPage({
path: node.frontmatter.slug,
component: moduleTemplate,
context: {
// additional data can be passed via context
slug: node.frontmatter.slug,
},
});
});
const syllabusTemplate = require.resolve(`./src/templates/syllabusTemplate.js`);
createPage({
path: "/",
component: syllabusTemplate,
context: {
division: 0
},
});
createPage({
path: "/intro",
component: syllabusTemplate,
context: {
division: 0
},
});
createPage({
path: "/general",
component: syllabusTemplate,
context: {
division: 1
},
});
createPage({
path: "/bronze",
component: syllabusTemplate,
context: {
division: 2
},
});
createPage({
path: "/silver",
component: syllabusTemplate,
context: {
division: 3
},
});
createPage({
path: "/gold",
component: syllabusTemplate,
context: {
division: 4
},
});
createPage({
path: "/plat",
component: syllabusTemplate,
context: {
division: 5
},
});
};
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions;
const typeDefs = `
type MarkdownRemarkFrontmatter implements Node {
prerequisites: [[String]]
}
`;
createTypes(typeDefs)
};
require = require('esm')(module);
module.exports = require('./gatsby-node.esm.js');

View file

@ -5,10 +5,14 @@
"version": "0.1.0",
"author": "Kyle Mathews <mathews.kyle@gmail.com>",
"dependencies": {
"@mdx-js/mdx": "^1.6.5",
"@mdx-js/react": "^1.6.5",
"@tailwindcss/ui": "^0.3.0",
"esm": "^3.2.25",
"gatsby": "^2.22.15",
"gatsby-image": "^2.4.5",
"gatsby-plugin-manifest": "^2.4.9",
"gatsby-plugin-mdx": "^1.2.15",
"gatsby-plugin-offline": "^3.2.7",
"gatsby-plugin-postcss": "^2.3.3",
"gatsby-plugin-react-helmet": "^3.3.2",

View file

@ -1,55 +1,14 @@
import React from "react";
import rehypeReact from "rehype-react"
import "../styles/markdown.css";
import "katex/dist/katex.min.css";
import "../styles/prism-theme.css";
import { MDXRenderer } from "gatsby-plugin-mdx";
const SpoilerComponent = ({ children }) => {
const [show, setShow] = React.useState(false);
return (
<div className={`px-4 border border-gray-200 rounded-md spoiler ${show?"spoiler--show":"spoiler--hide"}`}
onClick={e => {if (e.target.classList.contains("spoiler-label")) setShow(!show) }}>
{children}
</div>
);
};
const renderAst = new rehypeReact({
createElement: React.createElement,
components: {
details: SpoilerComponent,
summary: ({ children }) => (
<p className="spoiler-label py-4 flex items-start">
<svg className="h-6 w-6 text-gray-500 mr-4 spoiler-label__open" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
<svg className="h-6 w-6 text-gray-500 mr-4 spoiler-label__closed" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
{children}
</p>
),
"info-block": ({ children }) => (
<div className="rounded-md bg-blue-50 p-4 info-block mb-4">
<div className="flex">
<div className="flex-shrink-0">
<svg className="h-5 w-5 text-blue-400" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clipRule="evenodd" />
</svg>
</div>
<div className="ml-3">
{children}
</div>
</div>
</div>
)
},
}).Compiler;
const Markdown = ({ htmlAst, className }) => {
const Markdown = ({ body, className, excerptOnly = false }) => {
return (
<div className={`markdown ${className}`}>
{renderAst(htmlAst)}
<MDXRenderer excerptOnly={excerptOnly}>{body}</MDXRenderer>
</div>
);
};

View file

@ -1,4 +1,4 @@
import React from "react"
import * as React from "react"
const Layout = ({ children }) => {
return (

205
src/pages/index.tsx Normal file
View file

@ -0,0 +1,205 @@
import * as React from "react";
import {Link, PageProps} from "gatsby";
import Layout from "../components/layout";
import SEO from "../components/seo";
export default function IndexPage(props: PageProps) {
return (
<Layout>
<SEO title="" />
{/* Begin Hero */}
<div className="relative bg-white overflow-hidden">
<div className="hidden lg:block lg:absolute lg:inset-0">
<svg className="absolute top-0 left-1/2 transform translate-x-64 -translate-y-8" width="640" height="784"
fill="none" viewBox="0 0 640 784">
<defs>
<pattern id="9ebea6f4-a1f5-4d96-8c4e-4c2abf658047" x="118" y="0" width="20" height="20"
patternUnits="userSpaceOnUse">
<rect x="0" y="0" width="4" height="4" className="text-gray-200" fill="currentColor" />
</pattern>
</defs>
<rect y="72" width="640" height="640" className="text-gray-50" fill="currentColor" />
<rect x="118" width="404" height="784" fill="url(#9ebea6f4-a1f5-4d96-8c4e-4c2abf658047)" />
</svg>
</div>
<div className="relative pt-6 pb-16 md:pb-20 lg:pb-24 xl:pb-32 border-blue-600" style={{ borderTopWidth: "12px" }}>
<main className="mt-8 mx-auto max-w-6xl px-4 sm:mt-12 sm:px-6 md:mt-20 xl:mt-24">
<div className="lg:grid lg:grid-cols-12 lg:gap-8">
<div className="sm:text-center md:max-w-2xl md:mx-auto lg:col-span-6 lg:text-left lg:flex lg:flex-col lg:justify-center">
<h2
className="mt-1 text-4xl tracking-tight leading-10 font-extrabold text-gray-900 sm:leading-none sm:text-6xl lg:text-5xl xl:text-6xl">
USACO <span className="text-blue-600">Guide</span>
</h2>
<p className="mt-3 text-base text-gray-500 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
A free collection of <b>curated, high-quality resources</b> to take you from Bronze to Platinum and beyond.
</p>
<div className="mt-5 sm:mt-8 sm:flex sm:justify-center lg:justify-start">
<div className="rounded-md shadow">
<Link to="/intro"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-blue-600 hover:bg-blue-500 focus:outline-none focus:border-blue-700 focus:shadow-outline-blue transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10">
View Guide
</Link>
</div>
<div className="mt-3 sm:mt-0 sm:ml-3">
<a href="#learn-more"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-blue-700 bg-blue-100 hover:text-blue-600 hover:bg-blue-50 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10">
Learn More
</a>
</div>
</div>
</div>
<div
className="mt-12 relative sm:max-w-lg sm:mx-auto lg:mt-0 lg:max-w-none lg:mx-0 lg:col-span-6 lg:flex lg:items-center">
<svg
className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-8 scale-75 origin-top sm:scale-100 lg:hidden"
width="640" height="784" fill="none" viewBox="0 0 640 784">
<defs>
<pattern id="4f4f415c-a0e9-44c2-9601-6ded5a34a13e" x="118" y="0" width="20" height="20"
patternUnits="userSpaceOnUse">
<rect x="0" y="0" width="4" height="4" className="text-gray-200" fill="currentColor" />
</pattern>
</defs>
<rect y="72" width="640" height="640" className="text-gray-50" fill="currentColor" />
<rect x="118" width="404" height="784" fill="url(#4f4f415c-a0e9-44c2-9601-6ded5a34a13e)" />
</svg>
<div className="relative mx-auto xl:mr-0 w-full rounded-lg shadow-lg lg:max-w-md">
<a href="https://www.youtube.com/watch?v=ueNT-w7Oluw"
target="_blank"
className="relative block w-full rounded-lg overflow-hidden focus:outline-none focus:shadow-outline">
<img className="w-full"
src="https://img.youtube.com/vi/ueNT-w7Oluw/maxresdefault.jpg"
alt="Woman making a sale" />
<div className="absolute inset-0 w-full h-full flex items-center justify-center">
<svg className="h-20 w-20 text-blue-500" fill="currentColor" viewBox="0 0 84 84">
<circle opacity="0.9" cx="42" cy="42" r="42" fill="white" />
<path
d="M55.5039 40.3359L37.1094 28.0729C35.7803 27.1869 34 28.1396 34 29.737V54.263C34 55.8604 35.7803 56.8131 37.1094 55.9271L55.5038 43.6641C56.6913 42.8725 56.6913 41.1275 55.5039 40.3359Z" />
</svg>
</div>
</a>
</div>
</div>
</div>
</main>
</div>
</div>
{/* End Hero */}
<div className="py-12 bg-white">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="lg:text-center">
<p className="text-base leading-6 text-blue-600 font-semibold tracking-wide uppercase">About This Guide</p>
<h3
className="mt-2 text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl sm:leading-10">
Not Just Another Resource.
</h3>
<p className="mt-4 max-w-4xl text-xl leading-7 text-gray-500 lg:mx-auto">
This is more than "just another resource." This is the first-ever comprehensive, organized roadmap carefully designed and crafted for USACO contestants available to everyone, for free.
</p>
</div>
<div className="mt-12">
<ul className="md:grid md:grid-cols-2 md:col-gap-8 md:row-gap-10">
<li>
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">Experienced Authors</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
This guide is written by top USACO contestants, including two-time IOI winner and USACO Problemsetter <a href="https://github.com/bqi343" className="underline text-blue-500">Benjamin Qi</a>.
</p>
</div>
</div>
</li>
<li className="mt-10 md:mt-0">
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3" />
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">Calibrated Difficulty</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
This guide is targeted towards all contestants, regardless of their division. You'll find problems suitable for you.
</p>
</div>
</div>
</li>
<li className="mt-10 md:mt-0">
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">Improve Faster</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
Stop wasting time learning topics you already know. Skip over easy topics or delve deeper into difficult ones; the choice is yours.
</p>
</div>
</div>
</li>
<li className="mt-10 md:mt-0">
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z" />
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">Join the Community
</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
Stuck on a problem? Have a burning question to ask? Join the <a href="#" className="text-blue-500 underline">USACO Forum</a> to get help from other USACO members.
</p>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div className="bg-blue-900" id="learn-more">
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-20 text-center">
<p className="text-xl md:text-2xl font-bold text-blue-200">
Unsure how to get started?<br/>
Overwhelmed by too many resources?<br/>
Looking to take your CP skills to the next level?<br/>
</p>
<p className="text-3xl sm:text-4xl md:text-6xl font-extrabold text-white mt-8">This is the guide for you.</p>
<div className="mt-8 flex justify-center">
<div className="rounded-md shadow">
<Link to="/intro"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-blue-600 hover:bg-blue-500 focus:outline-none focus:border-blue-700 focus:shadow-outline-blue transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10">
View Guide
</Link>
</div>
</div>
</div>
</div>
</Layout>
)
}

View file

@ -109,7 +109,7 @@
}
.markdown ol {
@apply text-base pl-8 list-decimal;
@apply text-base pl-8 list-decimal mb-4;
}
.markdown kbd {
@ -137,17 +137,10 @@
display: none;
}
.spoiler--hide > *:not(.spoiler-label) {
display: none;
}
.spoiler--hide .spoiler-label__open {
display: none;
}
.spoiler--show .spoiler-label__closed {
display: none;
}
.spoiler-label {
margin-bottom: 0 !important;
.spoiler-body pre {
margin-left: -1rem !important;
margin-right: -1rem !important;
margin-bottom: -1rem !important;
}
.info-block .custom-block-heading {

View file

@ -14,65 +14,59 @@ const renderPrerequisite = (prerequisite) => {
);
};
export default function Template({
data, // this prop will be injected by the GraphQL query below.
}) {
const { markdownRemark } = data; // data.markdownRemark holds your post data
const { htmlAst } = markdownRemark;
const prereqs = markdownRemark.frontmatter.prerequisites;
export default function Template(props) {
const { mdx } = props.data; // data.markdownRemark holds your post data
const { body } = mdx;
const prereqs = mdx.frontmatter.prerequisites;
let division = 0;
if (markdownRemark.frontmatter.slug.includes("/general/")) division = 1;
if (markdownRemark.frontmatter.slug.includes("/bronze/")) division = 2;
if (markdownRemark.frontmatter.slug.includes("/silver/")) division = 3;
if (markdownRemark.frontmatter.slug.includes("/gold/")) division = 4;
if (markdownRemark.frontmatter.slug.includes("/plat/")) division = 5;
const divisions = ["intro", "general", "bronze", "silver", "gold", "plat"];
const division = props.pageContext.division;
return (
<Layout>
<div className="max-w-4xl mx-auto my-8">
<Link className="underline text-blue-600" to={"/"+divisions[division]+"/"}>&larr; Back to Home</Link>
<h1 className="mt-8 text-3xl font-bold">{markdownRemark.frontmatter.title}</h1>
<p className={`${prereqs ? "mb-4" : "mb-8"} text-gray-500`}>Author: {markdownRemark.frontmatter.author}</p>
<div className="px-4">
<Link className="underline text-blue-600" to={"/" + division + "/"}>&larr; Back to Home</Link>
<h1 className="mt-8 text-3xl font-bold">{mdx.frontmatter.title}</h1>
<p className={`${prereqs ? "mb-4" : "mb-8"} text-gray-500`}>Author: {mdx.frontmatter.author}</p>
{prereqs &&
<div className="rounded-md bg-blue-50 p-4 mb-12">
<div className="flex">
<div className="flex-shrink-0">
<svg className="h-5 w-5 text-blue-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clip-rule="evenodd" />
</svg>
</div>
<div className="ml-3">
<h3 className="text-sm leading-5 font-medium text-blue-800">
Prerequisites
</h3>
<div className="mt-2 text-sm leading-5 text-blue-800">
<ul className="list-disc list-inside pl-3 space-y-1">
{prereqs.map(renderPrerequisite)}
</ul>
{prereqs &&
<div className="rounded-md bg-blue-50 p-4 mb-12">
<div className="flex">
<div className="flex-shrink-0">
<svg className="h-5 w-5 text-blue-400" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clipRule="evenodd" />
</svg>
</div>
<div className="ml-3">
<h3 className="text-sm leading-5 font-medium text-blue-800">
Prerequisites
</h3>
<div className="mt-2 text-sm leading-5 text-blue-800">
<ul className="list-disc list-inside pl-3 space-y-1">
{prereqs.map(renderPrerequisite)}
</ul>
</div>
</div>
</div>
</div>
</div>}
</div>}
<Markdown htmlAst={htmlAst} className="markdown--module" />
<Markdown body={body} className="markdown--module" />
</div>
</div>
</Layout>
)
}
export const pageQuery = graphql`
query($slug: String!) {
markdownRemark(frontmatter: { slug: { eq: $slug } }) {
htmlAst
query($id: String!) {
mdx(frontmatter: { id: { eq: $id } }) {
body
frontmatter {
title
author
slug
id
prerequisites
}
}

View file

@ -2,24 +2,29 @@ import React from "react"
import Layout from "../components/layout"
import SEO from "../components/seo"
import SyllabusModule from "../components/SyllabusModule";
import { graphql, Link } from "gatsby";
import Markdown from "../components/Markdown";
import { divisionLabels, divisions } from "../../content/ordering";
import { getModule } from "../utils";
import SyllabusModule from "../components/SyllabusModule";
const renderModule = (node, idx, parentIdx = -1) => {
if (node.hasOwnProperty("items")) {
return node.items.map((x, i) => renderModule(x, i, idx));
}
const renderModule = ({ node }) => {
const data = node.frontmatter;
if (!data.title) return;
return (
<SyllabusModule
title={`${data.order}. ${data.title}`}
url={data.slug}
key={data.slug}
title={`${parentIdx !== -1 ? (parentIdx+1)+"." : ""}${idx+1}. ${data.title}`}
url={node.slug}
key={node.slug}
problems={data.problems}
prerequisites={data.prerequisites}
author={data.author}
>
<Markdown htmlAst={node.excerptAst} className="markdown--syllabus" />
{data.description}
</SyllabusModule>
);
};
@ -27,19 +32,22 @@ const renderModule = ({ node }) => {
export default function Template(props) {
const data = props.data;
const introModules = data.introModules.edges;
const generalModules = data.generalModules.edges;
const bronzeModules = data.bronzeModules.edges;
const silverModules = data.silverModules.edges;
const goldModules = data.goldModules.edges;
const platModules = data.platModules.edges;
const modules = [introModules, generalModules, bronzeModules, silverModules, goldModules, platModules];
const allModules = data.modules.edges.reduce((acc, cur) => {
acc[cur.node.frontmatter.id] = cur.node;
return acc;
}, {});
const [selectedDivision, setSelectedDivision] = React.useState(props.pathContext.division);
const colors = ["blue", "pink", "orange", "teal", "yellow", "purple"];
const [selectedDivision, setSelectedDivision] = React.useState(props.pageContext.division);
const colors = {
"intro": "blue",
"general": "pink",
"bronze": "orange",
"silver": "teal",
"gold": "yellow",
"plat": "purple"
};
const color = colors[selectedDivision];
const module = modules[selectedDivision];
console.log(module);
const module = getModule(allModules, selectedDivision);
// for purgecss, we have to list all the classes that are dynamically generated...
/*
@ -63,128 +71,121 @@ export default function Template(props) {
const handleDivisionChange = d => {
setSelectedDivision(d);
const divisions = ["intro", "general", "bronze", "silver", "gold", "plat"];
window.history.pushState(null, "", `/${divisions[d]}/`);
window.history.pushState(null, "", `/${d}/`);
};
return (
<Layout>
<SEO title="Home" />
{/* Begin Hero Section */}
<div className={`relative bg-${color}-600 overflow-hidden transition duration-300 pb-28`}>
<div className="hidden sm:block sm:absolute sm:inset-y-0 sm:h-full sm:w-full">
<div className="relative h-full max-w-screen-xl mx-auto">
<svg className="absolute right-full transform translate-y-1/4 translate-x-1/4 lg:translate-x-1/2"
width={404}
height={784} fill="none" viewBox="0 0 404 784">
<defs>
<pattern id="f210dbf6-a58d-4871-961e-36d5016a0f49" x={0} y={0} width={20} height={20}
patternUnits="userSpaceOnUse">
<rect x={0} y={0} width={4} height={4} className={`text-${color}-500 transition duration-300`} fill="currentColor" />
</pattern>
</defs>
<rect width={404} height={784} fill="url(#f210dbf6-a58d-4871-961e-36d5016a0f49)" />
</svg>
<svg
className="absolute left-full transform -translate-y-3/4 -translate-x-1/4 md:-translate-y-1/2 lg:-translate-x-1/2"
width={404} height={784} fill="none" viewBox="0 0 404 784">
<defs>
<pattern id="5d0dd344-b041-4d26-bec4-8d33ea57ec9b" x={0} y={0} width={20} height={20}
patternUnits="userSpaceOnUse">
<rect x={0} y={0} width={4} height={4} className={`text-${color}-500 transition duration-300`} fill="currentColor" />
</pattern>
</defs>
<rect width={404} height={784} fill="url(#5d0dd344-b041-4d26-bec4-8d33ea57ec9b)" />
</svg>
<div className="min-h-screen bg-gray-50">
{/* Begin Hero Section */}
<div className={`relative bg-${color}-600 overflow-hidden transition duration-300 pb-48`}>
<div className="hidden sm:block sm:absolute sm:inset-y-0 sm:h-full sm:w-full">
<div className="relative h-full max-w-screen-xl mx-auto">
<svg className="absolute right-full transform translate-y-1/4 translate-x-1/4 lg:translate-x-1/2"
width={404}
height={784} fill="none" viewBox="0 0 404 784">
<defs>
<pattern id="f210dbf6-a58d-4871-961e-36d5016a0f49" x={0} y={0} width={20} height={20}
patternUnits="userSpaceOnUse">
<rect x={0} y={0} width={4} height={4} className={`text-${color}-500 transition duration-300`} fill="currentColor" />
</pattern>
</defs>
<rect width={404} height={784} fill="url(#f210dbf6-a58d-4871-961e-36d5016a0f49)" />
</svg>
<svg
className="absolute left-full transform -translate-y-3/4 -translate-x-1/4 md:-translate-y-1/2 lg:-translate-x-1/2"
width={404} height={784} fill="none" viewBox="0 0 404 784">
<defs>
<pattern id="5d0dd344-b041-4d26-bec4-8d33ea57ec9b" x={0} y={0} width={20} height={20}
patternUnits="userSpaceOnUse">
<rect x={0} y={0} width={4} height={4} className={`text-${color}-500 transition duration-300`} fill="currentColor" />
</pattern>
</defs>
<rect width={404} height={784} fill="url(#5d0dd344-b041-4d26-bec4-8d33ea57ec9b)" />
</svg>
</div>
</div>
</div>
<div className="relative pt-6 pb-12 sm:pb-16 md:pb-20 lg:pb-28 xl:pb-32">
<div className="mt-10 mx-auto max-w-screen-xl px-4 sm:mt-12 sm:px-6 md:mt-16 lg:mt-20 xl:mt-28">
<div className="text-center">
<h2
className="text-4xl tracking-tight leading-10 font-extrabold text-white sm:text-5xl sm:leading-none md:text-6xl">
USACO Guide
</h2>
<p className={`mt-3 max-w-md mx-auto text-base text-${color}-300 sm:text-lg md:mt-5 md:text-xl md:max-w-3xl`}>
A collection of curated, high-quality resources to take you from Bronze to Platinum.
</p>
<div className="mt-5 max-w-md mx-auto sm:flex sm:justify-center md:mt-8">
<div className="rounded-md shadow">
<a href="#content"
className={`w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-${color}-500 hover:bg-${color}-50 hover:text-${color}-600 focus:outline-none focus:shadow-outline-${color} transition duration-300 ease-in-out md:py-4 md:text-lg md:px-10`}>
Get Started
</a>
<div className="relative pt-6 pb-12 sm:pb-16 md:pb-20 lg:pb-28 xl:pb-32">
<div className="mt-10 mx-auto max-w-screen-xl px-4 sm:mt-12 sm:px-6 md:mt-16 lg:mt-20 xl:mt-28">
<div className="text-center">
<h2
className="text-4xl tracking-tight leading-10 font-extrabold text-white sm:text-5xl sm:leading-none md:text-6xl">
USACO Guide
</h2>
<p className={`mt-3 max-w-md mx-auto text-base text-${color}-300 sm:text-lg md:mt-5 md:text-xl md:max-w-3xl`}>
A collection of curated, high-quality resources to take you from Bronze to Platinum.
</p>
<div className="mt-5 max-w-md mx-auto sm:flex sm:justify-center md:mt-8">
<div className="rounded-md shadow">
<Link to="/"
className={`w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-${color}-500 hover:bg-${color}-50 hover:text-${color}-600 focus:outline-none focus:shadow-outline-${color} transition duration-300 ease-in-out md:py-4 md:text-lg md:px-10`}>
About This Guide
</Link>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{/* End Hero Section */}
{/* End Hero Section */}
<div className="bg-gray-50 pb-8" id="content">
<div className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 pb-4">
<div className="mb-8 bg-white shadow-md rounded-lg relative" style={{ marginTop: "-8rem" }}>
<div className="sm:hidden">
<select aria-label="Selected tab"
className="form-select block w-full"
onChange={e => handleDivisionChange(e.target.value - '0')}
value={selectedDivision}
>
<option value={0}>Intro</option>
<option value={1}>General</option>
<option value={2}>Bronze</option>
<option value={3}>Silver</option>
<option value={4}>Gold</option>
<option value={5}>Platinum</option>
</select>
</div>
<div className="hidden sm:block border-b border-gray-200">
<nav className="flex -mb-px">
<a href="/intro"
onClick={e => {e.preventDefault(); handleDivisionChange(0)}}
className={selectedDivision === 0 ? selectedTabClasses : unselectedTabClasses}>
Intro
</a>
<a href="/general"
onClick={e => {e.preventDefault(); handleDivisionChange(1)}}
className={selectedDivision === 1 ? selectedTabClasses : unselectedTabClasses}>
General
</a>
<a href="/bronze"
onClick={e => {e.preventDefault(); handleDivisionChange(2)}}
className={selectedDivision === 2 ? selectedTabClasses : unselectedTabClasses}>
Bronze
</a>
<a href="/silver"
onClick={e => {e.preventDefault(); handleDivisionChange(3)}}
className={selectedDivision === 3 ? selectedTabClasses : unselectedTabClasses}>
Silver
</a>
<a href="/gold"
onClick={e => {e.preventDefault(); handleDivisionChange(4)}}
className={selectedDivision === 4 ? selectedTabClasses : unselectedTabClasses}>
Gold
</a>
<a href="/plat"
onClick={e => {e.preventDefault(); handleDivisionChange(5)}}
className={selectedDivision === 5 ? selectedTabClasses : unselectedTabClasses}>
Platinum
</a>
</nav>
<div className="pb-8" id="content">
<div className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 pb-4">
<div className="mb-8 bg-white shadow-md rounded-lg relative" style={{ marginTop: "-12rem" }}>
<div className="sm:hidden">
<select aria-label="Selected tab"
className="form-select block w-full"
onChange={e => handleDivisionChange(e.target.value)}
value={selectedDivision}
>
{divisions.map(division => (
<option key={division} value={division}>{divisionLabels[division]}</option>
))}
</select>
</div>
<div className="hidden sm:block border-b border-gray-200">
<nav className="flex -mb-px">
{divisions.map(division => (
<a key={division}
href={`/${division}`}
onClick={e => {e.preventDefault(); handleDivisionChange(division)}}
className={selectedDivision === division ? selectedTabClasses : unselectedTabClasses}>
{divisionLabels[division]}
</a>
))}
</nav>
</div>
<ol className="list-inside py-8 px-8 text-lg space-y-1">
{module.map((m, idx) => {
if (m.hasOwnProperty("items")) {
return (
<li key={m.name}>
<span className="inline-block w-4 text-right">{idx+1}. </span><span className="ml-2">{m.name}</span>
<ol className="list-inside px-6 text-lg space-y-1 mb-2">
{m.items.map((m, idx2) => (
<li key={m.slug}>
<span className="inline-block w-8 text-right">{idx+1}.{idx2+1}. </span><Link className="ml-2 text-blue-600 underline" to={m.slug}>{m.frontmatter.title}</Link>
</li>
))}
</ol>
</li>
)
}
return (
<li key={m.frontmatter.id}>
<span className="inline-block w-4 text-right">{idx+1}. </span><Link className="ml-2 text-blue-600 underline" to={m.slug}>{m.frontmatter.title}</Link>
</li>
);
})}
</ol>
</div>
<ol className="list-inside py-8 px-8 text-lg space-y-1">
{module.map(m => (
<li key={m.node.frontmatter.slug}>
{m.node.frontmatter.order}. <Link className="ml-2 text-blue-600 underline" to={m.node.frontmatter.slug}>{m.node.frontmatter.title}</Link>
</li>
))}
</ol>
{module.map((x, idx) => renderModule(x, idx))}
</div>
{module.map(renderModule)}
</div>
</div>
</Layout>
@ -192,99 +193,18 @@ export default function Template(props) {
}
export const pageQuery = graphql`
query {
introModules: allMarkdownRemark(sort: {fields: frontmatter___order}, filter: {fileAbsolutePath: {regex: "/1_Intro/"}}) {
modules: allMdx {
edges {
node {
id
frontmatter {
title
slug
id
author
problems
order
prerequisites
description
}
excerptAst
}
}
}
generalModules: allMarkdownRemark(sort: {fields: frontmatter___order}, filter: {fileAbsolutePath: {regex: "/2_General/"}}) {
edges {
node {
id
frontmatter {
title
slug
author
problems
order
prerequisites
}
excerptAst
}
}
}
bronzeModules: allMarkdownRemark(sort: {fields: frontmatter___order}, filter: {fileAbsolutePath: {regex: "/3_Bronze/"}}) {
edges {
node {
id
frontmatter {
title
slug
author
problems
order
prerequisites
}
excerptAst
}
}
}
silverModules: allMarkdownRemark(sort: {fields: frontmatter___order}, filter: {fileAbsolutePath: {regex: "/4_Silver/"}}) {
edges {
node {
id
frontmatter {
title
slug
author
problems
order
prerequisites
}
excerptAst
}
}
}
goldModules: allMarkdownRemark(sort: {fields: frontmatter___order}, filter: {fileAbsolutePath: {regex: "/5_Gold/"}}) {
edges {
node {
id
frontmatter {
title
slug
author
problems
order
prerequisites
}
excerptAst
}
}
}
platModules: allMarkdownRemark(sort: {fields: frontmatter___order}, filter: {fileAbsolutePath: {regex: "/6_Plat/"}}) {
edges {
node {
id
frontmatter {
title
slug
author
problems
order
prerequisites
}
excerptAst
}
}
}

29
src/utils.js Normal file
View file

@ -0,0 +1,29 @@
import ModuleOrdering from "../content/ordering";
export const getModule = (allModules, division) => {
return ModuleOrdering[division].map(k => {
// rip spaghetti code, clean this up
if (typeof k === "object") {
return {
name: k.name,
items: k.items.map(k2 => {
if (!allModules.hasOwnProperty(k2)) {
throw "Module not found: " + k2;
}
return {
...allModules[k2],
slug: `/${division}/${allModules[k2].frontmatter.id}`
};
})
}
} else {
if (!allModules.hasOwnProperty(k)) {
throw "Module not found: " + k;
}
return {
...allModules[k],
slug: `/${division}/${allModules[k].frontmatter.id}`
};
}
});
};

View file

@ -3,6 +3,6 @@ module.exports = {
require('@tailwindcss/ui'),
],
purge: {
content: ['./src/**/*.js'],
content: ['./src/**/*.js', "./src/**/*.ts", "./src/**/*.tsx"],
},
};

379
yarn.lock
View file

@ -40,7 +40,7 @@
semver "^5.4.1"
source-map "^0.5.0"
"@babel/core@^7.0.0", "@babel/core@^7.9.6":
"@babel/core@^7.0.0", "@babel/core@^7.10.2", "@babel/core@^7.9.6":
version "7.10.2"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.2.tgz#bd6786046668a925ac2bd2fd95b579b92a23b36a"
integrity sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==
@ -839,7 +839,7 @@
core-js "^2.6.5"
regenerator-runtime "^0.13.4"
"@babel/preset-env@^7.9.6":
"@babel/preset-env@^7.10.2", "@babel/preset-env@^7.9.6":
version "7.10.2"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.2.tgz#715930f2cf8573b0928005ee562bed52fb65fdfb"
integrity sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA==
@ -920,7 +920,7 @@
"@babel/types" "^7.4.4"
esutils "^2.0.2"
"@babel/preset-react@^7.9.4":
"@babel/preset-react@^7.10.1", "@babel/preset-react@^7.9.4":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.10.1.tgz#e2ab8ae9a363ec307b936589f07ed753192de041"
integrity sha512-Rw0SxQ7VKhObmFjD/cUcKhPTtzpeviEFX1E6PgP+cYOhQ98icNqtINNFANlsdbQHrmeWnqdxA4Tmnl1jy5tp3Q==
@ -3504,7 +3504,7 @@ blob@0.0.5:
resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683"
integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==
bluebird@^3.5.5, bluebird@^3.7.2:
bluebird@^3.0.5, bluebird@^3.5.5, bluebird@^3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
@ -3912,6 +3912,14 @@ camel-case@4.1.1:
pascal-case "^3.1.1"
tslib "^1.10.0"
camel-case@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=
dependencies:
no-case "^2.2.0"
upper-case "^1.1.1"
camelcase-css@2.0.1, camelcase-css@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
@ -4011,6 +4019,30 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
change-case@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.1.0.tgz#0e611b7edc9952df2e8513b27b42de72647dd17e"
integrity sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==
dependencies:
camel-case "^3.0.0"
constant-case "^2.0.0"
dot-case "^2.1.0"
header-case "^1.0.0"
is-lower-case "^1.1.0"
is-upper-case "^1.1.0"
lower-case "^1.1.1"
lower-case-first "^1.0.0"
no-case "^2.3.2"
param-case "^2.1.0"
pascal-case "^2.0.0"
path-case "^2.1.0"
sentence-case "^2.1.0"
snake-case "^2.1.0"
swap-case "^1.1.0"
title-case "^2.1.0"
upper-case "^1.1.1"
upper-case-first "^1.1.0"
character-entities-html4@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.4.tgz#0e64b0a3753ddbf1fdc044c5fd01d0199a02e125"
@ -4046,6 +4078,28 @@ charenc@~0.0.1:
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
cheerio@^0.22.0:
version "0.22.0"
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e"
integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=
dependencies:
css-select "~1.2.0"
dom-serializer "~0.1.0"
entities "~1.1.1"
htmlparser2 "^3.9.1"
lodash.assignin "^4.0.9"
lodash.bind "^4.1.4"
lodash.defaults "^4.0.1"
lodash.filter "^4.4.0"
lodash.flatten "^4.2.0"
lodash.foreach "^4.3.0"
lodash.map "^4.4.0"
lodash.merge "^4.4.0"
lodash.pick "^4.2.1"
lodash.reduce "^4.4.0"
lodash.reject "^4.4.0"
lodash.some "^4.4.0"
cheerio@^1.0.0-rc.3:
version "1.0.0-rc.3"
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6"
@ -4467,6 +4521,14 @@ console-stream@^0.1.1:
resolved "https://registry.yarnpkg.com/console-stream/-/console-stream-0.1.1.tgz#a095fe07b20465955f2fafd28b5d72bccd949d44"
integrity sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=
constant-case@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-2.0.0.tgz#4175764d389d3fa9c8ecd29186ed6005243b6a46"
integrity sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=
dependencies:
snake-case "^2.1.0"
upper-case "^1.1.1"
constants-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
@ -4558,7 +4620,7 @@ core-js-pure@^3.0.0:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813"
integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==
core-js@^2.4.0, core-js@^2.4.1, core-js@^2.6.11, core-js@^2.6.5:
core-js@2, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.6.11, core-js@^2.6.5:
version "2.6.11"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
@ -4955,6 +5017,11 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
dataloader@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-1.4.0.tgz#bca11d867f5d3f1b9ed9f737bd15970c65dff5c8"
integrity sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==
dataloader@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.0.0.tgz#41eaf123db115987e21ca93c005cd7753c55fe6f"
@ -5403,7 +5470,7 @@ dom-serializer@0, dom-serializer@^0.2.1:
domelementtype "^2.0.1"
entities "^2.0.0"
dom-serializer@~0.1.1:
dom-serializer@~0.1.0, dom-serializer@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0"
integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
@ -5470,6 +5537,13 @@ domutils@^2.0.0:
domelementtype "^2.0.1"
domhandler "^3.0.0"
dot-case@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-2.1.1.tgz#34dcf37f50a8e93c2b3bca8bb7fb9155c7da3bee"
integrity sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=
dependencies:
no-case "^2.2.0"
dot-prop@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
@ -5956,6 +6030,11 @@ eslint@^6.8.0:
text-table "^0.2.0"
v8-compile-cache "^2.0.3"
esm@^3.2.25:
version "3.2.25"
resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10"
integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==
espree@^6.1.2:
version "6.2.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a"
@ -6004,6 +6083,13 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
eval@^0.1.0, eval@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/eval/-/eval-0.1.4.tgz#e05dbe0dab4b9330215cbb7bf4886eb24bd58700"
integrity sha512-npGsebJejyjMRnLdFu+T/97dnigqIU0Ov3IGrZ8ygd1v7RL1vGkEKtvyWZobqUH1AQgKlg0Yqqe2BtMA9/QZLw==
dependencies:
require-like ">= 0.1.1"
event-source-polyfill@^1.0.14:
version "1.0.15"
resolved "https://registry.yarnpkg.com/event-source-polyfill/-/event-source-polyfill-1.0.15.tgz#a28e116281be677af4b055b67d95517e35c92435"
@ -6886,6 +6972,18 @@ gatsby-core-utils@^1.3.4:
proper-lockfile "^4.1.1"
xdg-basedir "^4.0.0"
gatsby-core-utils@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/gatsby-core-utils/-/gatsby-core-utils-1.3.5.tgz#3c8f2dc940cec6570d1317f02ba028f327d1e773"
integrity sha512-kbwJ5BeQ8OixJVuBb1AGRL6vdkFz9nFBa6gXqjQ6AAXHhYDrjOYrRMIENT1QLoabWo6tlh0Hyl1agfWaQwW8lg==
dependencies:
ci-info "2.0.0"
configstore "^5.0.1"
fs-extra "^8.1.0"
node-object-hash "^2.0.0"
proper-lockfile "^4.1.1"
xdg-basedir "^4.0.0"
gatsby-design-tokens@^2.0.2:
version "2.0.6"
resolved "https://registry.yarnpkg.com/gatsby-design-tokens/-/gatsby-design-tokens-2.0.6.tgz#593aa969e360560369fc59054c01236beed9be7d"
@ -6962,6 +7060,47 @@ gatsby-plugin-manifest@^2.4.9:
semver "^5.7.1"
sharp "^0.25.1"
gatsby-plugin-mdx@^1.2.15:
version "1.2.15"
resolved "https://registry.yarnpkg.com/gatsby-plugin-mdx/-/gatsby-plugin-mdx-1.2.15.tgz#359195813490873749fbcacc76151790b2db8451"
integrity sha512-qLtb4bvsEYDNyO/qrGgdjSUeNDH33uN+UZpG3OHz9UjVv4WxcYO1NfKbkjw3Uy62ajjcBr0zuyZJMm4WyQWu4w==
dependencies:
"@babel/core" "^7.10.2"
"@babel/generator" "^7.10.2"
"@babel/helper-plugin-utils" "^7.10.1"
"@babel/plugin-proposal-object-rest-spread" "^7.10.1"
"@babel/preset-env" "^7.10.2"
"@babel/preset-react" "^7.10.1"
"@babel/types" "^7.10.2"
camelcase-css "^2.0.1"
change-case "^3.1.0"
core-js "2"
dataloader "^1.4.0"
debug "^4.1.1"
escape-string-regexp "^1.0.5"
eval "^0.1.4"
fs-extra "^8.1.0"
gatsby-core-utils "^1.3.5"
gray-matter "^4.0.2"
json5 "^2.1.3"
loader-utils "^1.4.0"
lodash "^4.17.15"
mdast-util-to-string "^1.1.0"
mdast-util-toc "^3.1.0"
mime "^2.4.6"
p-queue "^5.0.0"
pretty-bytes "^5.3.0"
remark "^10.0.1"
remark-retext "^3.1.3"
retext-english "^3.0.4"
static-site-generator-webpack-plugin "^3.4.2"
style-to-object "^0.3.0"
underscore.string "^3.3.5"
unified "^8.4.2"
unist-util-map "^1.0.5"
unist-util-remove "^1.0.3"
unist-util-visit "^1.4.1"
gatsby-plugin-offline@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/gatsby-plugin-offline/-/gatsby-plugin-offline-3.2.7.tgz#6afab6c485dcc4cbbe433232703794ca8ac8407d"
@ -8161,6 +8300,14 @@ he@^1.1.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
header-case@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/header-case/-/header-case-1.0.1.tgz#9535973197c144b09613cd65d317ef19963bd02d"
integrity sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=
dependencies:
no-case "^2.2.0"
upper-case "^1.1.3"
hex-color-regex@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
@ -9013,6 +9160,13 @@ is-jpg@^2.0.0:
resolved "https://registry.yarnpkg.com/is-jpg/-/is-jpg-2.0.0.tgz#2e1997fa6e9166eaac0242daae443403e4ef1d97"
integrity sha1-LhmX+m6RZuqsAkLarkQ0A+TvHZc=
is-lower-case@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393"
integrity sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=
dependencies:
lower-case "^1.1.0"
is-natural-number@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8"
@ -9192,6 +9346,13 @@ is-unc-path@^1.0.0:
dependencies:
unc-path-regex "^0.1.2"
is-upper-case@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f"
integrity sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=
dependencies:
upper-case "^1.1.0"
is-url@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52"
@ -9424,7 +9585,7 @@ json5@^1.0.1:
dependencies:
minimist "^1.2.0"
json5@^2.1.2:
json5@^2.1.2, json5@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==
@ -9662,6 +9823,16 @@ lodash._reinterpolate@^3.0.0:
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
lodash.assignin@^4.0.9:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2"
integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI=
lodash.bind@^4.1.4:
version "4.2.1"
resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35"
integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=
lodash.clonedeep@4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
@ -9672,17 +9843,32 @@ lodash.debounce@^4.0.8:
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
lodash.defaults@^4.0.1:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
lodash.every@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.every/-/lodash.every-4.6.0.tgz#eb89984bebc4364279bb3aefbbd1ca19bfa6c6a7"
integrity sha1-64mYS+vENkJ5uzrvu9HKGb+mxqc=
lodash.filter@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=
lodash.flatten@^4.2.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
lodash.flattendeep@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=
lodash.foreach@^4.5.0:
lodash.foreach@^4.3.0, lodash.foreach@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=
@ -9692,7 +9878,7 @@ lodash.isequal@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
lodash.map@^4.6.0:
lodash.map@^4.4.0, lodash.map@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=
@ -9707,11 +9893,36 @@ lodash.memoize@^4.1.2:
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
lodash.merge@^4.4.0:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
lodash.pick@^4.2.1:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
lodash.reduce@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b"
integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=
lodash.reject@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415"
integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=
lodash.sample@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/lodash.sample/-/lodash.sample-4.2.1.tgz#5e4291b0c753fa1abeb0aab8fb29df1b66f07f6d"
integrity sha1-XkKRsMdT+hq+sKq4+ynfG2bwf20=
lodash.some@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=
lodash.template@^4.4.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
@ -9802,6 +10013,18 @@ loud-rejection@^2.2.0:
currently-unhandled "^0.4.1"
signal-exit "^3.0.2"
lower-case-first@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1"
integrity sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=
dependencies:
lower-case "^1.1.2"
lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
lower-case@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7"
@ -10029,6 +10252,16 @@ mdast-util-to-string@^1.0.5, mdast-util-to-string@^1.1.0:
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527"
integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==
mdast-util-toc@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/mdast-util-toc/-/mdast-util-toc-3.1.0.tgz#395eeb877f067f9d2165d990d77c7eea6f740934"
integrity sha512-Za0hqL1PqWrvxGtA/3NH9D5nhGAUS9grMM4obEAz5+zsk1RIw/vWUchkaoDLNdrwk05A0CSC5eEXng36/1qE5w==
dependencies:
github-slugger "^1.2.1"
mdast-util-to-string "^1.0.5"
unist-util-is "^2.1.2"
unist-util-visit "^1.1.0"
mdast-util-toc@^5.0:
version "5.0.3"
resolved "https://registry.yarnpkg.com/mdast-util-toc/-/mdast-util-toc-5.0.3.tgz#5fb1503e3655688929d596799a6910cc6548e420"
@ -10171,7 +10404,7 @@ mime@1.6.0, mime@^1.3.4:
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
mime@^2.0.3, mime@^2.4.4, mime@^2.4.5:
mime@^2.0.3, mime@^2.4.4, mime@^2.4.5, mime@^2.4.6:
version "2.4.6"
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1"
integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==
@ -10451,6 +10684,13 @@ nlcst-to-string@^2.0.0:
resolved "https://registry.yarnpkg.com/nlcst-to-string/-/nlcst-to-string-2.0.4.tgz#9315dfab80882bbfd86ddf1b706f53622dc400cc"
integrity sha512-3x3jwTd6UPG7vi5k4GEzvxJ5rDA7hVUIRNHPblKuMVP9Z3xmlsd9cgLcpAMkc5uPOBna82EeshROFhsPkbnTZg==
no-case@^2.2.0, no-case@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==
dependencies:
lower-case "^1.1.1"
no-case@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8"
@ -11025,6 +11265,13 @@ p-pipe@^1.1.0:
resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-1.2.0.tgz#4b1a11399a11520a67790ee5a0c1d5881d6befe9"
integrity sha1-SxoROZoRUgpneQ7loMHViB1r7+k=
p-queue@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-5.0.0.tgz#80f1741d5e78a6fa72fce889406481baa5617a3c"
integrity sha512-6QfeouDf236N+MAxHch0CVIy8o/KBnmhttKjxZoOkUlzqU+u9rZgEyXH3OdckhTgawbqf5rpzmyR+07+Lv0+zg==
dependencies:
eventemitter3 "^3.1.0"
p-reduce@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa"
@ -11085,6 +11332,13 @@ parallel-transform@^1.1.0:
inherits "^2.0.3"
readable-stream "^2.1.5"
param-case@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc=
dependencies:
no-case "^2.2.0"
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
@ -11254,6 +11508,14 @@ parseurl@^1.3.3, parseurl@~1.3.2, parseurl@~1.3.3:
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
pascal-case@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-2.0.1.tgz#2d578d3455f660da65eca18ef95b4e0de912761e"
integrity sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=
dependencies:
camel-case "^3.0.0"
upper-case-first "^1.1.0"
pascal-case@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f"
@ -11280,6 +11542,13 @@ path-browserify@0.0.1:
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==
path-case@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5"
integrity sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=
dependencies:
no-case "^2.2.0"
path-dirname@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
@ -12941,6 +13210,11 @@ require-directory@^2.1.1:
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
"require-like@>= 0.1.1":
version "0.1.2"
resolved "https://registry.yarnpkg.com/require-like/-/require-like-0.1.2.tgz#ad6f30c13becd797010c468afa775c0c0a6b47fa"
integrity sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=
require-main-filename@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
@ -13300,6 +13574,14 @@ send@0.17.1:
range-parser "~1.2.1"
statuses "~1.5.0"
sentence-case@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-2.1.1.tgz#1f6e2dda39c168bf92d13f86d4a918933f667ed4"
integrity sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=
dependencies:
no-case "^2.2.0"
upper-case-first "^1.1.2"
serialize-javascript@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
@ -13531,6 +13813,13 @@ slugify@^1.4.0:
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.4.0.tgz#c9557c653c54b0c7f7a8e786ef3431add676d2cb"
integrity sha512-FtLNsMGBSRB/0JOE2A0fxlqjI6fJsgHGS13iTuVT28kViI4JjUiNqp/vyis0ZXYcMnpR3fzGNkv+6vRlI2GwdQ==
snake-case@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f"
integrity sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=
dependencies:
no-case "^2.2.0"
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@ -13670,6 +13959,11 @@ sort-keys@^2.0.0:
dependencies:
is-plain-obj "^1.0.0"
source-list-map@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1"
integrity sha1-mIkBnRAkzOVc3AaUmDN+9hhqEaE=
source-list-map@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
@ -13704,7 +13998,7 @@ source-map@0.7.3, source-map@^0.7.3:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7:
source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.3:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
@ -13877,6 +14171,17 @@ static-extend@^0.1.1:
define-property "^0.2.5"
object-copy "^0.1.0"
static-site-generator-webpack-plugin@^3.4.2:
version "3.4.2"
resolved "https://registry.yarnpkg.com/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-3.4.2.tgz#ad9fd0a4fb8b6f439a7a66018320b459bdb6d916"
integrity sha512-39Kn+fZDVjolLYuX5y1rDvksJIW0QEUaEC/AVO/UewNXxGzoSQI1UYnRsL+ocAcN5Yti6d6rJgEL0qZ5tNXfdw==
dependencies:
bluebird "^3.0.5"
cheerio "^0.22.0"
eval "^0.1.0"
url "^0.11.0"
webpack-sources "^0.2.0"
"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
@ -14308,6 +14613,14 @@ svgo@1.3.2, svgo@^1.0.0:
unquote "~1.1.1"
util.promisify "~1.0.0"
swap-case@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3"
integrity sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=
dependencies:
lower-case "^1.1.1"
upper-case "^1.1.1"
symbol-observable@^1.0.4, symbol-observable@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
@ -14548,6 +14861,14 @@ tinycolor2@^1.4.1:
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8"
integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=
title-case@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa"
integrity sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=
dependencies:
no-case "^2.2.0"
upper-case "^1.0.3"
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@ -14958,7 +15279,7 @@ unist-util-generated@^1.0.0, unist-util-generated@^1.1.0:
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.5.tgz#1e903e68467931ebfaea386dae9ea253628acd42"
integrity sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw==
unist-util-is@^2.0.0:
unist-util-is@^2.0.0, unist-util-is@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.3.tgz#459182db31f4742fceaea88d429693cbf0043d20"
integrity sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==
@ -14973,6 +15294,13 @@ unist-util-is@^4.0.0:
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.0.2.tgz#c7d1341188aa9ce5b3cff538958de9895f14a5de"
integrity sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==
unist-util-map@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/unist-util-map/-/unist-util-map-1.0.5.tgz#701069b72e1d1cc02db265502a5e82b77c2eb8b7"
integrity sha512-dFil/AN6vqhnQWNCZk0GF/G3+Q5YwsB+PqjnzvpO2wzdRtUJ1E8PN+XRE/PRr/G3FzKjRTJU0haqE0Ekl+O3Ag==
dependencies:
object-assign "^4.0.1"
unist-util-modify-children@^1.0.0:
version "1.1.6"
resolved "https://registry.yarnpkg.com/unist-util-modify-children/-/unist-util-modify-children-1.1.6.tgz#1587130ca0ab5c56155fa60837ff524c3fbfbfaa"
@ -14999,6 +15327,13 @@ unist-util-remove-position@^2.0.0:
dependencies:
unist-util-visit "^2.0.0"
unist-util-remove@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-1.0.3.tgz#58ec193dfa84b52d5a055ffbc58e5444eb8031a3"
integrity sha512-mB6nCHCQK0pQffUAcCVmKgIWzG/AXs/V8qpS8K72tMPtOSCMSjDeMc5yN+Ye8rB0FhcE+JvW++o1xRNc0R+++g==
dependencies:
unist-util-is "^3.0.0"
unist-util-remove@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.0.0.tgz#32c2ad5578802f2ca62ab808173d505b2c898488"
@ -15121,6 +15456,18 @@ update-notifier@^3.0.1:
semver-diff "^2.0.0"
xdg-basedir "^3.0.0"
upper-case-first@^1.1.0, upper-case-first@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115"
integrity sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=
dependencies:
upper-case "^1.1.1"
upper-case@^1.0.3, upper-case@^1.1.0, upper-case@^1.1.1, upper-case@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=
uri-js@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
@ -15489,6 +15836,14 @@ webpack-merge@^4.2.2:
dependencies:
lodash "^4.17.15"
webpack-sources@^0.2.0:
version "0.2.3"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb"
integrity sha1-F8Yr+vE8cH+dAsR54Nzd6DgGl/s=
dependencies:
source-list-map "^1.1.1"
source-map "~0.5.3"
webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1:
version "1.4.3"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933"