fixed unmerged files

This commit is contained in:
Michael Cao 2020-07-17 20:51:29 -05:00
commit d5f3429fd4
142 changed files with 2020 additions and 1981 deletions

View file

@ -1,5 +1,7 @@
.cache
package.json
package-lock.json
yarn.lock
public
content
content
docs
static

View file

@ -9,8 +9,8 @@ As much as possible, please try to keep the markdown files independent of the fr
## Documentation
- To get this site running locally, refer to the [Front End Documentation](Front%20End%20Documentation.md).
- For information regarding Content Writing, refer to the [Content Documentation](Content%20Documentation.md).
- To get this site running locally, refer to the [Front End Documentation](docs/Front%20End%20Documentation.md).
- For information regarding Content Writing, refer to the [Content Documentation](docs/Content%20Documentation.md).
## Tech Stack

View file

@ -30,10 +30,10 @@ If you aren't comfortable with basic coding yet, you can use the resources below
### General
<resources title="Learning to Code">
<resource title="Sololearn" url="https://www.sololearn.com/">courses for C++, Java, Python</resource>
<resource title="Codecademy" url="https://www.codecademy.com/">free courses for C++, Java, Python 2</resource>
</resources>
<Resources title="Learning to Code">
<Resource title="Sololearn" url="https://www.sololearn.com/">courses for C++, Java, Python</Resource>
<Resource title="Codecademy" url="https://www.codecademy.com/">free courses for C++, Java, Python 2</Resource>
</Resources>
<LanguageSection>
@ -41,15 +41,15 @@ If you aren't comfortable with basic coding yet, you can use the resources below
Use one of the resources above or below (or find your own) to learn C++. If you use Sololearn, you don't have to complete the full course; we recommend you finish everything up to (but not including) "More on Classes."
<resources title="C++">
<resource source="PAPS" title="2 - Programming in C++" starred>lots of examples, Kattis exercises</resource>
</resources>
<Resources title="C++">
<Resource source="PAPS" title="2 - Programming in C++" starred>lots of examples, Kattis exercises</Resource>
</Resources>
<info-block title="Pro Tip">
<Info title="Pro Tip">
You do not need to learn pointers (for now). Knowledge of structs and classes is useful but not required.
</info-block>
</Info>
</CPPSection>

View file

@ -13,9 +13,9 @@ Everything should compile assuming that the templates below are included. If any
## General
<resources>
<resource source = "CF" title = "Swift - Competitive C++ Manifesto" url="blog/entry/64218"> some material directly from this blog post</resource>
</resources>
<Resources>
<Resource source = "CF" title = "Swift - Competitive C++ Manifesto" url="blog/entry/64218"> some material directly from this blog post</Resource>
</Resources>
- Indenting with either tabs or 4 spaces is fine.
- Binary operators should be spaced on both sides. For example, `a+b` should be written as `a + b` and `x=a+b` should be written as `x = a + b`.

View file

@ -54,23 +54,23 @@ See [clist.by](https://clist.by/coder/bqi343/) for an extensive list of contests
Let me know if there's something else I should try to qualify for!
<resources>
<resource source="Google" title="Code Jam" url="https://codingcompetitions.withgoogle.com/codejam/">25 from R3</resource>
<resource source="TopCoder" title="Open" url="https://tco20.topcoder.com/competition-overview/algorithm/algorithm-ways">16; 4 from SRMs, 10 from R4, 2 from wildcard</resource>
<resource source="Facebook" title="Hacker Cup" url="https://www.facebook.com/hackercup/">25 from R3</resource>
<resource source="AtCoder" title="World Tour Finals" url="https://codeforces.com/blog/entry/56623">8 from AGC</resource>
</resources>
<Resources>
<Resource source="Google" title="Code Jam" url="https://codingcompetitions.withgoogle.com/codejam/">25 from R3</Resource>
<Resource source="TopCoder" title="Open" url="https://tco20.topcoder.com/competition-overview/algorithm/algorithm-ways">16; 4 from SRMs, 10 from R4, 2 from wildcard</Resource>
<Resource source="Facebook" title="Hacker Cup" url="https://www.facebook.com/hackercup/">25 from R3</Resource>
<Resource source="AtCoder" title="World Tour Finals" url="https://codeforces.com/blog/entry/56623">8 from AGC</Resource>
</Resources>
## US High School
Only considering contests which allow C++ since the others aren't legit. (add more?)
<resources>
<resource source="Virginia Tech" title="HSPC" url="https://icpc.cs.vt.edu/#/hscontest2017">December, online, teams of 3, 5 hours, past problems on <a href="https://icpc.cs.vt.edu/#/hscontest2017">Kattis</a></resource>
<resource source="University of Central Florida" title="HSPT" url="https://hspt.ucfprogrammingteam.org/index.php/hspt-online-edition">Decmeber, online, individual, 4 hours</resource>
<resource source="Cornell" title="HSPC" url="https://www.cs.cornell.edu/events/cornell-high-school-programming-contest">April, teams of 3, 3 hours, <a href="https://cornell-hspc19.kattis.com/problems">2019 problems</a></resource>
<resource source="Montgomery Blair HS" title="mBIT" url="https://mbit.mbhs.edu/">online, teams of 4, 4 hours</resource>
</resources>
<Resources>
<Resource source="Virginia Tech" title="HSPC" url="https://icpc.cs.vt.edu/#/hscontest2017">December, online, teams of 3, 5 hours, past problems on <a href="https://icpc.cs.vt.edu/#/hscontest2017">Kattis</a></Resource>
<Resource source="University of Central Florida" title="HSPT" url="https://hspt.ucfprogrammingteam.org/index.php/hspt-online-edition">Decmeber, online, individual, 4 hours</Resource>
<Resource source="Cornell" title="HSPC" url="https://www.cs.cornell.edu/events/cornell-high-school-programming-contest">April, teams of 3, 3 hours, <a href="https://cornell-hspc19.kattis.com/problems">2019 problems</a></Resource>
<Resource source="Montgomery Blair HS" title="mBIT" url="https://mbit.mbhs.edu/">online, teams of 4, 4 hours</Resource>
</Resources>
## Codeforces Tools

View file

@ -7,11 +7,11 @@ prerequisites:
- running-code
---
<resources>
<resource source="IUSACO" title="2.2 - Data Types">module is based off this</resource>
<resource source="CPH" title="1.1 to 1.3 - Introduction"></resource>
<resource source="PAPS" title="2.3 - Variables & Types"></resource>
</resources>
<Resources>
<Resource source="IUSACO" title="2.2 - Data Types">module is based off this</Resource>
<Resource source="CPH" title="1.1 to 1.3 - Introduction"></Resource>
<Resource source="PAPS" title="2.3 - Variables & Types"></Resource>
</Resources>
<br />

View file

@ -11,29 +11,29 @@ description: "Debugging your code is an extremely important skill. Here are some
<CPPSection>
<resources>
<resource
<Resources>
<Resource
source="Errichto"
title="Video - How to test your solution"
url="https://www.youtube.com/watch?v=JXTVOyQpSGM"
starred
>
using a script to stress test
</resource>
<resource
</Resource>
<Resource
source="Errichto"
title="Asking for help FAQ"
url="https://codeforces.com/blog/entry/64993"
starred
>
some parts from above video
</resource>
</resources>
</Resource>
</Resources>
### Style
<resources>
<resource
<Resources>
<Resource
source="CF"
title="Competitive C++ Manifesto: A Style Guide"
url="blog/entry/64218"
@ -41,32 +41,32 @@ description: "Debugging your code is an extremely important skill. Here are some
>
{' '}
don't agree with everything but important to read nonetheless
</resource>
</resources>
</Resource>
</Resources>
### Assertions & Warnings
<resources>
<resource
<Resources>
<Resource
title="Asserts"
source="LearnCpp"
url="https://www.learncpp.com/cpp-tutorial/7-12a-assert-and-static_assert/"
starred
>
includes static_assert and #define NDEBUG
</resource>
<resource title="Assertions" source="GFG" url="assertions-cc">
</Resource>
<Resource title="Assertions" source="GFG" url="assertions-cc">
subset of above
</resource>
<resource
</Resource>
<Resource
title="Diagnostics"
source="GNU"
url="https://gcc.gnu.org/onlinedocs/cpp/Diagnostics.html"
starred
>
#warning, #error
</resource>
</resources>
</Resource>
</Resources>
### Printing Variables
@ -95,17 +95,17 @@ Includes `-Wall -Wextra -Wshadow`
[Variable shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) should be avoided whenever possible.
<resources>
<resource source="CF" title="andreyv - Catching Mistakes with GCC" url="https://codeforces.com/blog/entry/15547">more options</resource>
</resources>
<Resources>
<Resource source="CF" title="andreyv - Catching Mistakes with GCC" url="https://codeforces.com/blog/entry/15547">more options</Resource>
</Resources>
### Other Options
<warning-block>
<Warning>
Ben - I don't use these because they can significantly slow down compilation time and I don't find these messages particularly helpful (But maybe I'm wrong? I'm not so familiar with these.)
</warning-block>
</Warning>
In Errichto's blog he says that he uses the following as part of his compilation command:
@ -135,7 +135,7 @@ zsh: segmentation fault ./prog
`g++ prog.cpp -o prog -fsanitize=address && ./prog` produces:
<spoiler title="AddressSanitizer">
<Spoiler title="AddressSanitizer">
```
AddressSanitizer:DEADLYSIGNAL
@ -157,11 +157,11 @@ SUMMARY: AddressSanitizer: SEGV (prog:x86_64+0x100001325) in main
zsh: abort ./prog
```
</spoiler>
</Spoiler>
Finally, `g++ prog.cpp -o prog -D_GLIBCXX_DEBUG -g && ./prog` produces:
<spoiler title="Debug">
<Spoiler title="Debug">
```
/usr/local/Cellar/gcc/9.2.0_1/include/c++/9.2.0/debug/vector:427:
@ -184,7 +184,7 @@ Objects involved in the operation:
zsh: abort ./prog
```
</spoiler>
</Spoiler>
Another example with `prog.cpp` as the following:
@ -211,7 +211,7 @@ prog.cpp:6:13: runtime error: load of address 0x7ffee0a77a94 with insufficient s
`g++ prog.cpp -o prog -fsanitize=address && ./prog` produces:
<spoiler title="AddressSanitizer">
<Spoiler title="AddressSanitizer">
```
=================================================================
@ -264,7 +264,7 @@ Shadow byte legend (one shadow byte represents 8 application bytes):
zsh: abort ./prog
```
</spoiler>
</Spoiler>
## Running (on Mac)

View file

@ -40,24 +40,24 @@ In particular, contestants using Java should be familiar with roughly the first
You may find the following resources helpful for familiarizing yourself with your language of choice. Resources below (including starred ones) are optional.
<resources>
<resource source="CodeSignal" title="Arcade, Interview Practice" url="https://codesignal.com/" starred>can practice basics</resource>
<resource source="Philippines OI" title="Prepare" url="https://noi.ph/prepare/" starred>lots of links!</resource>
<resource source="VPlanet" title="Learn to Code" url="https://www.vplanetcoding.com/course1">basic problems, mostly loops</resource>
<resource source="IOI" title="Getting Started" url="https://ioinformatics.org/page/getting-started/14">not up to date</resource>
<resource source="Quora" title="Joshua Pan - Schedule for Beginners" url="https://www.quora.com/What-is-a-good-schedule-to-follow-for-becoming-better-at-competitive-programming-for-beginners">generally good, although CSES problemset (see "Resources") is definitely a better place to start than USACO Training or Codechef</resource>
</resources>
<Resources>
<Resource source="CodeSignal" title="Arcade, Interview Practice" url="https://codesignal.com/" starred>can practice basics</Resource>
<Resource source="Philippines OI" title="Prepare" url="https://noi.ph/prepare/" starred>lots of links!</Resource>
<Resource source="VPlanet" title="Learn to Code" url="https://www.vplanetcoding.com/course1">basic problems, mostly loops</Resource>
<Resource source="IOI" title="Getting Started" url="https://ioinformatics.org/page/getting-started/14">not up to date</Resource>
<Resource source="Quora" title="Joshua Pan - Schedule for Beginners" url="https://www.quora.com/What-is-a-good-schedule-to-follow-for-becoming-better-at-competitive-programming-for-beginners">generally good, although CSES problemset (see "Resources") is definitely a better place to start than USACO Training or Codechef</Resource>
</Resources>
## Introductory Problems
The following require relatively little programming experience and no algorithmic knowledge.
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
Also check the [CSES Introductory Problems](https://cses.fi/problemset/list/) up to and including "Palindrome Reorder." Once you're done with these, you should continue onto Bronze.
<warning-block>
<Warning>
Some modules in the "Intro" section (ex. Fast Input & Output) are not relevant for USACO Bronze contestants. It is probably best to skip these for now and return to these later. However, make sure to check [Code Conventions](./code-con) for the templates that will be used for code snippets in later modules!
</warning-block>
</Warning>

View file

@ -19,7 +19,7 @@ Although both Python and Java receive two times the C++ time limit in USACO, thi
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.
<spoiler title="Python3 8/10 Solution">
<Spoiler title="Python3 8/10 Solution">
```py
# 8/10 test cases ...
@ -92,11 +92,11 @@ fout.write(str(-1 if lo == 0 else ed[lo-1][0]))
fout.write('\n')
```
</spoiler>
</Spoiler>
A similar solution in Java requires almost 3s, which is fairly close to the time limit of 4s.
<spoiler title="Java Solution">
<Spoiler title="Java Solution">
```java
import java.io.*; // from Nick Wu
@ -166,11 +166,11 @@ public class wormsort {
}
```
</spoiler>
</Spoiler>
A comparable C++ solution runs in less than 700ms.
<spoiler title="C++ Solution">
<Spoiler title="C++ Solution">
```cpp
#include <bits/stdc++.h>
@ -226,4 +226,4 @@ int main() {
cout << minW;
}
```
</spoiler>
</Spoiler>

View file

@ -19,7 +19,7 @@ The largest USACO input file I know of is test case 11 of [USACO Platinum - Robo
The slowest method.
<spoiler title="973ms">
<Spoiler title="973ms">
```cpp
#include <bits/stdc++.h>
@ -40,13 +40,13 @@ int main() {
}
```
</spoiler>
</Spoiler>
### Method 2: `freopen` with `scanf`
Significantly faster.
<spoiler title="281ms">
<Spoiler title="281ms">
```cpp
#include <bits/stdc++.h> // 281 ms
@ -66,13 +66,13 @@ int main() {
}
```
</spoiler>
</Spoiler>
### Method 3: `ifstream` and `ofstream`
About as fast.
<spoiler title="258ms">
<Spoiler title="258ms">
```cpp
#include <bits/stdc++.h>
@ -93,13 +93,13 @@ int main() { // 258 ms
}
```
</spoiler>
</Spoiler>
### A Faster Method
I we use FastIO from [here](https://github.com/bqi343/USACO/blob/master/Implementations/content/various/FastIO.h) then the runtime is further reduced.
<spoiler title="91ms">
<Spoiler title="91ms">
```cpp
using namespace FastIO;
@ -119,35 +119,35 @@ int main() {
}
```
</spoiler>
</Spoiler>
### Significance of `ios_base::sync_with_stdio(0); cin.tie(0);`
Adding this line as the first line of `main()` reduced the runtime of the first method to 254 ms.
<resources>
<resource
<Resources>
<Resource
source="CF"
url="blog/entry/5217"
title="Yet again on C++ I/O"
starred
>
timing various I/O methods
</resource>
<resource
</Resource>
<Resource
source="SO"
url="https://stackoverflow.com/questions/31162367/significance-of-ios-basesync-with-stdiofalse-cin-tienull"
title="Significance of [above]"
>
{' '}
</resource>
<resource source="CPP" url="http://www.cplusplus.com/reference/ios/ios_base/sync_with_stdio/" title="ios_base::sync_with_stdio">
</Resource>
<Resource source="CPP" url="http://www.cplusplus.com/reference/ios/ios_base/sync_with_stdio/" title="ios_base::sync_with_stdio">
documentation
</resource>
<resource source="CPP" url="http://www.cplusplus.com/reference/ios/ios/tie/" title="ios::tie">
</Resource>
<Resource source="CPP" url="http://www.cplusplus.com/reference/ios/ios/tie/" title="ios::tie">
documentation
</resource>
</resources>
</Resource>
</Resources>
You may see `cin.sync_with_stdio(0);` used in place of `ios_base::sync_with_stdio(0);` but they should have the same effect.
@ -161,7 +161,7 @@ Keep in mind that a Java program that only reads in $N$ and outputs a number tak
[`Scanner`](https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html) is probably the easiest way to read input in Java, though it is also extremely slow.
<spoiler title="3188ms">
<Spoiler title="3188ms">
```java
import java.util.*;
@ -190,7 +190,7 @@ public class roboherd_scanner {
}
```
</spoiler>
</Spoiler>
A common alternative to reading input for programming contests is [`BufferedReader`](https://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html), which reads faster from a file than `Scanner`. `BufferedReader` reads line-by-line with the `.readLine()` method, which returns a string. Methods like `Integer.parseInt()` are used to convert strings into primitives, and they can directly convert a line into a number, like in `Integer.parseInt(br.readLine())`.
@ -198,7 +198,7 @@ Reading input is more complicated when multiple, space-separated values are plac
_Reading input with `BufferedReader` and `.split()`_:
<spoiler title="1209ms">
<Spoiler title="1209ms">
```java
import java.util.*;
@ -229,11 +229,11 @@ public class roboherd_buffered_reader_string_split {
}
```
</spoiler>
</Spoiler>
_Reading input with `BufferedReader` and `StringTokenizer`_:
<spoiler title="986ms">
<Spoiler title="986ms">
```java
import java.util.*;
@ -264,11 +264,11 @@ public class roboherd_buffered_reader_string_tokenizer {
}
```
</spoiler>
</Spoiler>
_Reading input with `BufferedReader` and `StreamTokenizer`_:
<spoiler title="569ms">
<Spoiler title="569ms">
```java
import java.util.*;
@ -299,11 +299,11 @@ public class roboherd {
}
```
</spoiler>
</Spoiler>
Faster methods of reading input exist too - Even faster than `BufferedReader` is a custom-written Fast I/O class that uses `InputStream`. Note that this custom class is similar to the custom-written `FastIO.h` in the C++ section, as both read input through a byte buffer.
<spoiler title="320ms">
<Spoiler title="320ms">
```java
import java.util.*;
@ -414,7 +414,7 @@ public class roboherd_is {
}
```
</spoiler>
</Spoiler>
The most realistic input method to implement in contest is `BufferedReader`, as it is relatively fast for the amount of code necessary.
@ -424,7 +424,7 @@ The most realistic input method to implement in contest is `BufferedReader`, as
Faster than the first C++ method! Significantly less if $P$ does not need to be stored.
<spoiler title="853ms">
<Spoiler title="853ms">
```py
fin = open("roboherd.in","r")
@ -439,7 +439,7 @@ else:
fout.write(str(1000000000000000000))
```
</spoiler>
</Spoiler>
</PySection>

View file

@ -26,11 +26,11 @@ export const metadata = {
}
};
<resources>
<resource source="IUSACO" title="2.1 - Input and Output">module is based off this</resource>
<resource source="CPH" title="1.2 - Input and Output">cin, getline, files</resource>
<resource source="PAPS" title="2.4 - Input and Output">cin, getline</resource>
</resources>
<Resources>
<Resource source="IUSACO" title="2.1 - Input and Output">module is based off this</Resource>
<Resource source="CPH" title="1.2 - Input and Output">cin, getline, files</Resource>
<Resource source="PAPS" title="2.4 - Input and Output">cin, getline</Resource>
</Resources>
<!-- We use `using namespace std;` so that we don't have to preface standard library functions with `std::` each time we use them. -->
@ -38,7 +38,7 @@ export const metadata = {
In most websites (such as CodeForces and CSES), input and output are **standard**.
<problems-list problems={metadata.problems.cses} />
<Problems problems={metadata.problems.cses} />
Note that this problem requires **64-bit integers**.
@ -170,7 +170,7 @@ public static void main(String[] args) {
## File I/O
<problems-list problems={metadata.problems.fence} />
<Problems problems={metadata.problems.fence} />
In USACO, input is read from a file called `problemname.in`. After the program is run, output must be printed to a file called `problemname.out`. Note that you'll have to rename the `.in` and `.out` files depending on the problem. For example, in the above problem you would use `paint.in` and `paint.out`.
@ -268,9 +268,9 @@ instead. There is no need for this since `PrintWriter` [uses buffered output](ht
## Example Solutions - Fence Painting
<resources>
<resource source="USACO" title="Technical Specifications for Contests" url="http://www.usaco.org/index.php?page=instructions" starred>Make sure to read this.</resource>
</resources>
<Resources>
<Resource source="USACO" title="Technical Specifications for Contests" url="http://www.usaco.org/index.php?page=instructions" starred>Make sure to read this.</Resource>
</Resources>
<br />

View file

@ -14,21 +14,21 @@ For each problem, you submit the completed code to a grader, which checks the an
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. You don't need to bother documenting your code because it only needs to be readable to you during the contest. That being said, you probably want to maintain a bare minimum level of readability so you can keep track of what's going on.
<!-- <optional-content title="More Information"> -->
<!-- <Optional title="More Information"> -->
<div class="yt-video-container my-8"><iframe width="560" height="315" src="https://www.youtube.com/embed/ueNT-w7Oluw" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
<resources>
<resource source="William Lin" title="Video - What is Competitive Programming?" url="https://www.youtube.com/watch?time_continue=1&v=ueNT-w7Oluw">video shown above</resource>
<resource source="Kamil Debowski" title="Video - Interview with a Competitive Programmer" url="https://www.youtube.com/watch?v=F4rykKLcduI"></resource>
<resource source="CPH" title="1 - Introduction">algorithms & programming contests</resource>
<resource source="IUSACO" title="1 - The Beginning"></resource>
<resource source="PAPS" title="1 - Algorithms & Problems">examples of algorithms</resource>
</resources>
<Resources>
<Resource source="William Lin" title="Video - What is Competitive Programming?" url="https://www.youtube.com/watch?time_continue=1&v=ueNT-w7Oluw">video shown above</Resource>
<Resource source="Kamil Debowski" title="Video - Interview with a Competitive Programmer" url="https://www.youtube.com/watch?v=F4rykKLcduI"></Resource>
<Resource source="CPH" title="1 - Introduction">algorithms & programming contests</Resource>
<Resource source="IUSACO" title="1 - The Beginning"></Resource>
<Resource source="PAPS" title="1 - Algorithms & Problems">examples of algorithms</Resource>
</Resources>
[Task](https://open.kattis.com/contests/mcpc19open/problems/basketballoneonone) that was mentioned in Kamil's video.
<!-- </optional-content> -->
<!-- </Optional> -->
## USACO Contest Format

View file

@ -67,31 +67,31 @@ Some modules may also have additional content at the end that isn't needed for U
Sometimes modules will contain interactive elements. Here are some of the more common ones.
<info-block title="Pro Tip">
<Info title="Pro Tip">
Helpful bits of advice provided by the author.
<!-- Tips on how to become legend in CP and better at competitve programming by Benjamin Qi, exactly what you wanted when you spam DM'd him! Definitely take these tips seriously. Don't uncomment this. -->
</info-block>
</Info>
<spoiler title="Hidden Content">
<Spoiler title="Hidden Content">
In some modules, codes or solutions will be placed in **spoiler blocks** like this. In these cases, you should think about the problem or try to implement it yourself before revealing the solution or code.
</spoiler>
</Spoiler>
<optional-content title="Optional Content">
<Optional title="Optional Content">
Not all content in this guide is essential to competitive programming. Skipping over optional content is fine, but if you're interested, feel free to explore further as well.
</optional-content>
</Optional>
<warning-block>
<Warning>
A warning block like this will contain common errors that you should avoid.
</warning-block>
</Warning>
<!-- Difficulty should be comparable across a division. Say that you have *almost-solved* a question if you scored at least $n-2$ out of $n$ test cases. At least for platinum, difficulty levels should correspond approximately to the following USA Pre-college almost-solve rates on a USACO contest:

View file

@ -25,14 +25,14 @@ description: Once you've reached Platinum, it may be helpful to practice with pr
The [OI Checklist](https://oichecklist.pythonanywhere.com/) is a great way to track your progress. :)
<resources>
<resource source="IZhO" title="International Zhautykov Olympiad (Kazakhstan)" url="https://izho.kz/"></resource>
<resource source="APIO" title="Asia-Pacific Informatics Olympiad" url="http://apio-olympiad.org/"></resource>
<resource source="COCI" title="Croatian Open Contests in Informatics" url="http://hsin.hr/coci/">not full feedback ...</resource>
<resource source="JOI" title="Japanese Olympiad in Informatics" url="https://www.ioi-jp.org/"></resource>
<resource source="LMIO" title="Lithuanian Olympiad in Informatics" url="http://online.lmio.lt/"></resource>
<resource source="InfO(1) Cup" title="InfO(1) Cup" url="http://info1cup.com/"></resource>
</resources>
<Resources>
<Resource source="IZhO" title="International Zhautykov Olympiad (Kazakhstan)" url="https://izho.kz/"></Resource>
<Resource source="APIO" title="Asia-Pacific Informatics Olympiad" url="http://apio-olympiad.org/"></Resource>
<Resource source="COCI" title="Croatian Open Contests in Informatics" url="http://hsin.hr/coci/">not full feedback ...</Resource>
<Resource source="JOI" title="Japanese Olympiad in Informatics" url="https://www.ioi-jp.org/"></Resource>
<Resource source="LMIO" title="Lithuanian Olympiad in Informatics" url="http://online.lmio.lt/"></Resource>
<Resource source="InfO(1) Cup" title="InfO(1) Cup" url="http://info1cup.com/"></Resource>
</Resources>
## [IOI](https://ioinformatics.org/)
@ -49,10 +49,10 @@ Misc:
## [CSES](https://cses.fi/)
<resources>
<resource source="BOI" title="Baltic Olympiad in Informatics" url="http://www.boi2017.org/">2017 website</resource>
<resource source="CEOI" title="Central European Olympiad in Informatics" url="http://ceoi.inf.elte.hu/"> </resource>
</resources>
<Resources>
<Resource source="BOI" title="Baltic Olympiad in Informatics" url="http://www.boi2017.org/">2017 website</Resource>
<Resource source="CEOI" title="Central European Olympiad in Informatics" url="http://ceoi.inf.elte.hu/"> </Resource>
</Resources>
## Other

View file

@ -96,6 +96,6 @@ I think the most important thing regarding practicing is to try to get something
## Additional
<resources>
<resource source="CF" title="E869120 - A Way to Practice CP" url="blog/entry/53341">going from CF rating 1000 to 2000</resource>
</resources>
<Resources>
<Resource source="CF" title="E869120 - A Way to Practice CP" url="blog/entry/53341">going from CF rating 1000 to 2000</Resource>
</Resources>

View file

@ -10,7 +10,7 @@ Anyone can propose problems for monthly contests. Email your proposal to Profess
- 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">
<Spoiler title="2020 Open Gold - Favorite Colors">
```
http://www.usaco.org/index.php?page=viewproblem2&cpid=1042
@ -64,4 +64,4 @@ favorite color 1.
[/section]
```
</spoiler>
</Spoiler>

View file

@ -25,13 +25,13 @@ Please let us know if these installation instructions do not work for you.
- okay ... has the bare minimum you need
- sometimes erases your code when you first create it (so get in the habit of copying your code first)
<warning-block>
<Warning>
If you use Ideone during an online contest (such as a Codeforces round), you **must** ensure that your code is set to be private. **You might be punished for cheating if another person finds and copies your code during the contest, even if you never intentionally provide the code to anyone.**
Even if you are not doing an online contest, you might want to set your code to be private for other reasons.
</warning-block>
</Warning>
You can also share code with [pastebin](https://pastebin.com/) or [hastebin](https://hastebin.com/).
@ -46,17 +46,17 @@ You can run from the command line and use a text editor of your choice.
## Text Editors
<resources>
<resource title="Sublime Text 3" url="https://www.sublimetext.com/" starred>
<Resources>
<Resource title="Sublime Text 3" url="https://www.sublimetext.com/" starred>
Fast, lightweight. Keeps asking you to purchase a license ...
</resource>
<resource title="Atom" url="https://atom.io/">
</Resource>
<Resource title="Atom" url="https://atom.io/">
From the makers of Github.
</resource>
<resource title="Vim" url="https://www.vim.org/">
</Resource>
<Resource title="Vim" url="https://www.vim.org/">
Classic text editor, usually preinstalled on Linux.
</resource>
</resources>
</Resource>
</Resources>
Vim is probably the easiest way to print syntax-highlighted code on Mac, see the response to [this post](https://stackoverflow.com/questions/1656914/printing-code-with-syntax-highlighting).
@ -68,16 +68,16 @@ Vim is probably the easiest way to print syntax-highlighted code on Mac, see the
- Using `/usr/local/bin/subl` instead of `~/bin/subl` worked for me on OS X Mojave.
- [Package - Sublime Linter (GCC)](https://packagecontrol.io/packages/SublimeLinter-gcc)
- highlights compilation errors and warnings from `-Wall`
- [Package - Fast Olympic Coding](https://github.com/Jatana/FastOlympicCoding) (I don't use)
- test manager can be useful
- linting is covered by the above
- stress testing is covered in "Debugging"
- can't get debug to work
<!-- - [Editing Build Settings](https://stackoverflow.com/questions/23789410/how-to-edit-sublime-text-build-settings)
- no need to do this if you just use command line to compile & run -->
<!-- - [FastOlympicCoding Addon](https://github.com/Jatana/FastOlympicCoding)
- not that useful
- stress testing is covered in "Debugging"
- linting is covered by the above
- debugger only works with clang
- [Editing Build Settings](https://stackoverflow.com/questions/23789410/how-to-edit-sublime-text-build-settings)
- no need to do this if you just use command line to compile & run
-->
## On Linux
@ -116,20 +116,20 @@ If you want to code in (neo)vim, you can install WSL and code through WSL bash.
1. Open the **Terminal** application and familiarize yourself with some basic commands.
<resources>
<resource
<Resources>
<Resource
source="Jim Hoskins"
title="Intro to OS X Command Line"
url="https://blog.teamtreehouse.com/introduction-to-the-mac-os-x-command-line"
starred
></resource>
<resource
></Resource>
<Resource
source="Rahul Saigal"
title="Mac Terminal Cheat Sheet"
url="https://www.makeuseof.com/tag/mac-terminal-commands-cheat-sheet/"
starred
></resource>
</resources>
></Resource>
</Resources>
2. Install XCode command line tools.
@ -233,17 +233,17 @@ You should always compile with these flags.
### Adding Shortcuts (Mac and Linux only)
<info-block title="Windows Users">
<Info title="Windows Users">
If you're on Windows, you can use an IDE to get these shortcuts, or you can install WSL (mentioned above).
</info-block>
</Info>
Of course, retyping the flags above can get tedious. You should define shortcuts so you don't need to type them every time!
<resources>
<resource source="Jonathan Suh" url="https://jonsuh.com/blog/bash-command-line-shortcuts/" title="Aliases in Terminal" starred></resource>
</resources>
<Resources>
<Resource source="Jonathan Suh" url="https://jonsuh.com/blog/bash-command-line-shortcuts/" title="Aliases in Terminal" starred></Resource>
</Resources>
Open your `.zshenv` with TextEdit:
@ -288,17 +288,17 @@ python3 --version # prints Python 3.8.1
# Using an IDE
<resources>
<resource source="IOI" title="2019 Contest Environment" url="https://ioi2019.az/en-content-26.html"> </resource>
</resources>
<Resources>
<Resource source="IOI" title="2019 Contest Environment" url="https://ioi2019.az/en-content-26.html"> </Resource>
</Resources>
<LanguageSection>
<CPPSection>
These often have C++ support already built-in.
<resources>
<resource
<Resources>
<Resource
source="Microsoft" title="Visual Studio Code"
url="https://code.visualstudio.com/"
starred
@ -306,27 +306,27 @@ These often have C++ support already built-in.
Lightweight, fast IDE, but requires some configuration. See{' '}
<a href="http://www.csc.kth.se/~jsannemo/slask/main.pdf">PAPC 2.1</a> for
setup instructions.
</resource>
<resource source=" " title="Geany" url="https://www.geany.org/" starred>
</Resource>
<Resource source=" " title="Geany" url="https://www.geany.org/" starred>
Lightweight, frequently used at IOI.
</resource>
<resource source="Microsoft" title="Visual Studio" url="https://visualstudio.microsoft.com/vs/">
</Resource>
<Resource source="Microsoft" title="Visual Studio" url="https://visualstudio.microsoft.com/vs/">
Heavier cousin of VS Code. VS Code is better for competitive programming.
</resource>
<resource source=" " title="Codeblocks" url="http://www.codeblocks.org/">
</Resource>
<Resource source=" " title="Codeblocks" url="http://www.codeblocks.org/">
Bad on Mac.
</resource>
<resource source="Apple" title="XCode" url="https://developer.apple.com/xcode/">
</Resource>
<Resource source="Apple" title="XCode" url="https://developer.apple.com/xcode/">
Mac only.
</resource>
<resource source="Jetbrains" title="CLion" url="https://www.jetbrains.com/clion/">
</Resource>
<Resource source="Jetbrains" title="CLion" url="https://www.jetbrains.com/clion/">
Requires a license, but{' '}
<a href="https://www.jetbrains.com/community/education/#students">
free for students
</a>
.
</resource>
</resources>
</Resource>
</Resources>
</CPPSection>
@ -334,18 +334,18 @@ These often have C++ support already built-in.
It can be useful to use a Java IDE to take advantage of the powerful debugging features in Java.
<resources>
<resource source="Jetbrains" title="IntelliJ IDEA" url="https://www.jetbrains.com/idea/">
<Resources>
<Resource source="Jetbrains" title="IntelliJ IDEA" url="https://www.jetbrains.com/idea/">
costs money but is{' '}
<a href="https://www.jetbrains.com/community/education/#students">
free for students
</a>
.
</resource>
<resource source="Eclipse" title="IDE" url="https://www.eclipse.org/eclipseide/">
</Resource>
<Resource source="Eclipse" title="IDE" url="https://www.eclipse.org/eclipseide/">
Freely available
</resource>
</resources>
</Resource>
</Resources>
</JavaSection>

View file

@ -9,24 +9,24 @@ description: "?"
Use in place of separately including libraries.
<resources>
<resource source="CPH" title="1.1 - C++ Code Template" starred></resource>
<resource source="GFG" title="GFG - <bits/stdc++.h>" url="bitsstdc-h-c"> </resource>
</resources>
<Resources>
<Resource source="CPH" title="1.1 - C++ Code Template" starred></Resource>
<Resource source="GFG" title="GFG - <bits/stdc++.h>" url="bitsstdc-h-c"> </Resource>
</Resources>
## Macros
<resources>
<resource source="CPH" title="1.4 - Shortening Code" starred></resource>
<resource source="GFG" url="cc-preprocessors" title="Macros"></resource>
<resource
<Resources>
<Resource source="CPH" title="1.4 - Shortening Code" starred></Resource>
<Resource source="GFG" url="cc-preprocessors" title="Macros"></Resource>
<Resource
source="GCC"
url="https://gcc.gnu.org/onlinedocs/cpp/Macros.html"
title="Online Docs - Macros"
>
reference
</resource>
</resources>
</Resource>
</Resources>
## `typedef`, `using`
@ -121,24 +121,24 @@ Instructions (Mac):
## Lambda Expressions
<resources>
<resource
<Resources>
<Resource
source="GFG"
url="lambda-expression-in-c"
title="Lambda Expressions in C++"
>
{' '}
</resource>
</resources>
</Resource>
</Resources>
(describe more)
### Recursive Lambdas
<resources>
<resource source="open-std" url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html" title="Y Combinator Proposal" starred> </resource>
<resource source="RIP Tutorial" url="https://riptutorial.com/cplusplus/example/8508/recursive-lambdas" title="Recursive Lambdas"> </resource>
</resources>
<Resources>
<Resource source="open-std" url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html" title="Y Combinator Proposal" starred> </Resource>
<Resource source="RIP Tutorial" url="https://riptutorial.com/cplusplus/example/8508/recursive-lambdas" title="Recursive Lambdas"> </Resource>
</Resources>
We can do stuff like the following in C++14:

View file

@ -5,9 +5,9 @@ author: Benjamin Qi
description: ""
---
<resources>
<resource source="Quora" title="What is it like to attend USACO Camp?" url="https://www.quora.com/What-is-it-like-to-attend-the-USACO-training-camp" starred> </resource>
</resources>
<Resources>
<Resource source="Quora" title="What is it like to attend USACO Camp?" url="https://www.quora.com/What-is-it-like-to-attend-the-USACO-training-camp" starred> </Resource>
</Resources>
Each of the \~26 finalists is either a **Holstein** or a **Guernsey**.
@ -22,14 +22,14 @@ Contests are 3-5 hrs with 3-4 problems each ~~and are frequently extended for lu
## Selection
<resources>
<resource source="USACO" title="The Road to the IOI Team" url="http://www.usaco.org/index.php?page=contests" starred>16..24 students is no longer accurate</resource>
<resource source="Quora" title="How do I get into USACO Camp?" url="https://www.quora.com/How-do-I-get-into-the-USACO-training-camp" starred>See Brian's response.</resource>
<resource source="Quora" title="Is USACO Training Progress used in the selection of USACO Finalists?" url="https://www.quora.com/Is-progress-in-the-USACO-Training-Gateway-used-in-the-selection-of-USACO-finalists">nice we have conflicting answers</resource>
<resource source="Jelani Nelson" title="2011-20 USACO Camp Unique Participants by State" url="https://tinyurl.com/usacomap">what an amazing distribution</resource>
</resources>
<Resources>
<Resource source="USACO" title="The Road to the IOI Team" url="http://www.usaco.org/index.php?page=contests" starred>16..24 students is no longer accurate</Resource>
<Resource source="Quora" title="How do I get into USACO Camp?" url="https://www.quora.com/How-do-I-get-into-the-USACO-training-camp" starred>See Brian's response.</Resource>
<Resource source="Quora" title="Is USACO Training Progress used in the selection of USACO Finalists?" url="https://www.quora.com/Is-progress-in-the-USACO-Training-Gateway-used-in-the-selection-of-USACO-finalists">nice we have conflicting answers</Resource>
<Resource source="Jelani Nelson" title="2011-20 USACO Camp Unique Participants by State" url="https://tinyurl.com/usacomap">what an amazing distribution</Resource>
</Resources>
<optional-content title="excerpt from 'How do I get into USACO Camp?'">
<Optional title="excerpt from 'How do I get into USACO Camp?'">
> A few answers mention how to train, so I won't focus on that (I didn't train).
@ -37,15 +37,15 @@ Contests are 3-5 hrs with 3-4 problems each ~~and are frequently extended for lu
> But even I made it to camp. So you'll have no problem.
</optional-content>
</Optional>
Campers generally average at least one problem and some partial credit per contest (where "some" varies a lot).
<info-block title="Pro Tip">
<Info title="Pro Tip">
Submitting all the sample cases ~~might increase your total score by half a problem across the whole season!!~~
</info-block>
</Info>
### First-time campers by grade level

View file

@ -58,11 +58,11 @@ For lower level contestants, the guide is generally<Asterisk>There are some exce
## About This Guide
<warning-block title="This guide is NOT a syllabus!!">
<Warning title="This guide is NOT a syllabus!!">
Topics on this guide reflect _past_ problems, not _future_ problems. Contest problems may contain topics that aren't mentioned in this guide, and topics that appear in one division of this guide may appear in lower divisions in future contests.
</warning-block>
</Warning>
- For Bronze, Silver, and Gold contestants, we aim to be a "**one stop shop**," meaning that this is the only site you have to use to be exposed to most (if not all) of the topics required for Bronze - Gold.<Asterisk>Of course, you should still use other websites as necessary.</Asterisk>
- We'll link to online resources that already exist whenever possible instead of rewriting tutorials ourselves.

View file

@ -33,10 +33,10 @@ export const metadata = {
}
};
<resources>
<resource source="IUSACO" title="6 - Simulation">module is based off this</resource>
<resource source="CPH" title="5.1 to 5.3 - Complete Search"> </resource>
</resources>
<Resources>
<Resource source="IUSACO" title="6 - Simulation">module is based off this</Resource>
<Resource source="CPH" title="5.1 to 5.3 - Complete Search"> </Resource>
</Resources>
<br />
@ -58,7 +58,7 @@ The third line contains $N$ integers, the $y$-coordinates of the poitnts: $y_1,
Print one integer, the square of the maximum Euclidean distance between any two of the points.
<spoiler title="Solution">
<Spoiler title="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 `X[]` and `Y[]`, such that `X[i]` and `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.
@ -109,14 +109,14 @@ 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 an integer 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 will probably work, but you should generally stay with integers whenever possible.
</spoiler>
</Spoiler>
## Problems
### Easier
<problems-list problems={metadata.problems.easier} />
<Problems problems={metadata.problems.easier} />
### Harder
<problems-list problems={metadata.problems.harder} />
<Problems problems={metadata.problems.harder} />

View file

@ -25,21 +25,21 @@ export const metadata = {
}
};
<problems-list problems={metadata.problems.permSam} />
<Problems problems={metadata.problems.permSam} />
<br />
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!)$.
<resources>
<resource source="GFG" url="write-a-c-program-to-print-all-permutations-of-a-given-string" title="Printing all Permutations of Given String"> </resource>
</resources>
<Resources>
<Resource source="GFG" url="write-a-c-program-to-print-all-permutations-of-a-given-string" title="Printing all Permutations of Given String"> </Resource>
</Resources>
## Lexicographical Order
This term is mentioned quite frequently:
<problems-list problems={metadata.problems.ex} />
<Problems problems={metadata.problems.ex} />
Think about how are words ordered in a dictionary. (In fact, this is where the term "lexicographical" comes from.)
@ -73,9 +73,9 @@ What's going to be in the `check` function depends on the problem, but it should
### Method 2
<resources>
<resource source="Mark Nelson" title="Next Permutation" url="https://marknelson.us/posts/2002/03/01/next-permutation.html"> </resource>
</resources>
<Resources>
<Resource source="Mark Nelson" title="Next Permutation" url="https://marknelson.us/posts/2002/03/01/next-permutation.html"> </Resource>
</Resources>
Alternatively, we can just use the [`next_permutation()`](https://en.cppreference.com/w/cpp/algorithm/next_permutation) function. This function takes in a range and modifies it to the next greater permutation. If there is no greater permutation, it returns false. To iterate through all permutations, place it inside a `do-while` loop. We are using a `do-while` loop here instead of a typical `while` loop because a `while` loop would modify the smallest permutation before we got a chance to process it.
@ -125,4 +125,4 @@ public class Test {
### Problems
<problems-list problems={metadata.problems.perm} />
<Problems problems={metadata.problems.perm} />

View file

@ -20,12 +20,12 @@ export const metadata = {
}
};
<resources>
<resource source="IUSACO" title="4.1 - Dynamic Arrays">module is based off this</resource>
<resource source="CPH" title="4.1 - Dynamic Arrays" starred>vectors, strings</resource>
<resource source="PAPS" title="3.1 - Vectors, 6.1 - Dynamic Arrays">how dynamic arrays work</resource>
<resource source="CPC" title="2 - Data Structures" url="02_data_structures">assumes prior experience</resource>
</resources>
<Resources>
<Resource source="IUSACO" title="4.1 - Dynamic Arrays">module is based off this</Resource>
<Resource source="CPH" title="4.1 - Dynamic Arrays" starred>vectors, strings</Resource>
<Resource source="PAPS" title="3.1 - Vectors, 6.1 - Dynamic Arrays">how dynamic arrays work</Resource>
<Resource source="CPC" title="2 - Data Structures" url="02_data_structures">assumes prior experience</Resource>
</Resources>
<br />
@ -278,7 +278,7 @@ for(auto element : v) {
## Sorting
<problems-list problems={metadata.problems.bubble} />
<Problems problems={metadata.problems.bubble} />
**Sorting** refers to arranging items in some particular order. You do not need to know how to sort an array in $O(N\log N)$ time for Bronze, but you should be aware of how to use built-in methods to sort a (possibly dynamic) array.
@ -321,4 +321,4 @@ Two ways to avoid this:
## Problems
<problems-list problems={metadata.problems.easy} />
<Problems problems={metadata.problems.easy} />

View file

@ -30,14 +30,14 @@ Graphs can be used to represent many things, from images to wireless signals, bu
Both of these tasks will be covered in higher divisions. For now, it suffices to learn how graphs are represented.
<resources>
<resource source="CSA" title="Introduction to Graphs" url="introduction_to_graphs" starred>interactive</resource>
<resource source="CSA" title="Graph Representations" url="graph_representation" starred>interactive - adjacency lists and matrices</resource>
<resource source="CPH" title="11 - Basics of Graphs" starred>graph terminology, representation</resource>
<resource source="IUSACO" title="10.1 to 10.3 - Graph Theory" starred>graph basics and representation, trees</resource>
<resource source="PAPS" title="6.4 - Graphs">adjacency matrices, lists, maps</resource>
<resource source="TC" title="Intro to Graphs Section 1" url="introduction-to-graphs-and-their-data-structures-section-1"></resource>
</resources>
<Resources>
<Resource source="CSA" title="Introduction to Graphs" url="introduction_to_graphs" starred>interactive</Resource>
<Resource source="CSA" title="Graph Representations" url="graph_representation" starred>interactive - adjacency lists and matrices</Resource>
<Resource source="CPH" title="11 - Basics of Graphs" starred>graph terminology, representation</Resource>
<Resource source="IUSACO" title="10.1 to 10.3 - Graph Theory" starred>graph basics and representation, trees</Resource>
<Resource source="PAPS" title="6.4 - Graphs">adjacency matrices, lists, maps</Resource>
<Resource source="TC" title="Intro to Graphs Section 1" url="introduction-to-graphs-and-their-data-structures-section-1"></Resource>
</Resources>
## What Should You Know for Bronze?
@ -45,4 +45,4 @@ Both of these tasks will be covered in higher divisions. For now, it suffices to
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -0,0 +1,175 @@
---
id: intro-greedy
title: Introduction to Greedy Algorithms
author: Michael Cao, Darren Yao
description: "Selecting the optimal choice at each step in your algorithm without looking at the solution space as a whole."
frequency: 2
---
import { Problem } from "../models";
export const metadata = {
problems: {
tutorial: [
new Problem("Bronze", "Mad Scientist", "1012", "Normal", false, [], ""),
],
general: [
new Problem("Bronze", "Cow Tipping", "689", "Hard", false, [], "Cells in the last row and column can be toggled uniquely. Toggle the appropriate ones and then recurse to the rectangle in the previous row/column, and solve the same way."),
new Problem("Bronze", "Race", "989", "Very Hard", false, [], "Greedily increment/decrement Bessies speed to fit the conditions until her total distance exceeds K."),
],
}
};
## Ad Hoc
Most bronze problems fall into specific categories, such as simulation and complete search. Those which don't often require more thought, although they are not necessarily more difficult to implement.
Any problem that doesn't fall under any well-defined category can be labelled as **Ad Hoc**. Since there is no fixed algorithm or idea to solving these problems, they can be hard to generalize. In this module, we'll go over some general tips that may be useful in approaching these problems.
<ul>
<li> Draw lots of small cases to gain a better understanding of the problem. If you're having trouble debugging, draw more cases. If you don't know how to start with a problem, draw more cases. Whenever you don't know how to further approach a problem, you're probably missing an important observation, so draw more cases and make observations about properties of the problem. </li>
<li> Whenever you find an observation that seems useful, write it down! Writing down ideas lets you easily come back to them later, and makes sure you don't forget about ideas that could potentially be the solution. </li>
<li> Don't get stuck on any specific idea, unless you see an entire solution. Trying to complete search an Ad Hoc problem could end up wasting a lot of your time in contest. </li>
<li> Try to approach the problem from a lot of different perspectives. Try to draw a visual depiction of the problem, mess around with formulas, or draw a graph (see Graph Theory module). One of the most helpful things you can do when solving Ad Hoc problems is to keep trying ideas until you make progress. This is something you get better at as you do more problems.</li>
</ul>
These tips are helpful in solving Ad Hoc problems. However, in the end, the best way to get better at Ad Hoc problems (or any type of problems) is to do a lot of them. Try to solve as many practice problems below as you can, and click the solution sketch tab if you can't figure the solution out.
## Greedy Algorithms
Most USACO Bronze problems that appear to be Ad Hoc can actually be solved using **greedy** algorithms. This idea will be covered in a future [module](../silver/greedy), but we'll introduce the general mindset in this section.
<Resources>
<Resource source="CPH" title="6.1 - Coin Problem" starred>other examples are outside scope of bronze</Resource>
</Resources>
From the above:
> A **greedy** algorithm constructs a solution to the problem by always making a
choice that looks the best at the moment. A greedy algorithm never takes back
its choices, but directly constructs the final solution. For this reason, greedy
algorithms are usually very efficient.
**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.
### Example: Studying Algorithms
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
<Spoiler title="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)$.
<LanguageSection>
<CPPSection>
```cpp
// read in the input, store the algorithms in a vector, algorithms
sort(algorithms.begin(), algorithms.end());
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++;
}
cout << i << endl; // print the ans
```
</CPPSection>
<JavaSection>
```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();
```
</JavaSection>
</LanguageSection>
</Spoiler>
### 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:
<center>
| Item | Weight | Value | Value Per Weight |
|------|--------|-------|------------------|
| A | 3 | 18 | 6 |
| B | 2 | 10 | 5 |
| C | 2 | 10 | 5 |
</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.
### Example: Mad Scientist
Try to come up with a greedy algorithm for the USACO Bronze problem "Mad Scientist."
<Problems problems={metadata.problems.tutorial} />
<Spoiler title="Correct Greedy Algorithm">
In this problem, the correct greedy solution is to continually flip the longest possible ranges of mismatching cows.
Mad Scientist has an excellent [editorial](http://www.usaco.org/current/data/sol_breedflip_bronze_feb20.html) with a video solution and intuitive proof.
It is highly recommended you read it to gain a better understanding of the greedy algorithm.
</Spoiler>
However, not all greedy problems in the bronze division necessarily require mathematical proofs of correctness. It is often sufficent to intuitively convince yourself your algorithm is correct.
<Info title="Pro Tip">
Sometimes, if the algorithm is easy enough to implement, you don't even need to convince yourself it's correct; just code it and see if it passes. Competitive programmers refer to this as "Proof by AC," or "Proof by Accepted."
<!-- Don't overuse it though? -->
</Info>
## Problems
<Problems problems={metadata.problems.general} />
<IncompleteSection>
</IncompleteSection>
<!-- Anything else major that needs to be added? Bronze Ad Hoc is not very complicated. -->

View file

@ -17,22 +17,22 @@ If you sort one of $x_i$ and $y_i$ without considering the other, the points wil
<CPPSection />
<PySection>
<warning-block title="Language Note">
<Warning title="Language Note">
**Pairs are not available in Python.** Just use tuples; no need for pairs!
</warning-block>
</Warning>
<IncompleteSection />
</PySection>
<JavaSection>
<warning-block title="Language Note">
<Warning title="Language Note">
**Pairs and tuples are not available in Java.** If you are using Java, just skip this module.
</warning-block>
</Warning>
<IncompleteSection />
@ -126,9 +126,9 @@ int main() {
## Sorting Pairs & Tuples
<resources>
<resource source="CPH" title="3.2 - Comparison Operators" starred></resource>
</resources>
<Resources>
<Resource source="CPH" title="3.2 - Comparison Operators" starred></Resource>
</Resources>
By default, C++ pairs are sorted by first element and then second element in case of a tie, which is precisely what we need for the example above.
@ -172,11 +172,11 @@ Use the link below (if you know of a better one, please let us know!) to learn a
Python automatically sorts a list of tuples by the first element, then the second, and so on. This can save you time and keystrokes for certain problems like the one above.
<resources>
<Resources>
<resource source="Tutorialspoint" title="Python Tuples" url="https://www.tutorialspoint.com/python/python_tuples.htm" starred />
<Resource source="Tutorialspoint" title="Python Tuples" url="https://www.tutorialspoint.com/python/python_tuples.htm" starred />
</resources>
</Resources>
</PySection>

View file

@ -20,9 +20,9 @@ export const metadata = {
}
};
<resources>
<resource source="IUSACO" title="7.1 - Rectangle Geometry">module is based off this</resource>
</resources>
<Resources>
<Resource source="IUSACO" title="7.1 - Rectangle Geometry">module is based off this</Resource>
</Resources>
<br/>
@ -30,13 +30,13 @@ Most only include two or three squares or rectangles, in which case you can simp
## Example: Blocked Billboard
<problems-list problems={metadata.problems.blocked} />
<Problems problems={metadata.problems.blocked} />
### Naive Solution
Since all coordinates are in the range $[-1000,1000]$, we can simply go through each of the $2000^2$ possible visible squares and check which ones are visible using nested for loops.
<spoiler title="Nested Loops">
<Spoiler title="Nested Loops">
<LanguageSection>
@ -72,7 +72,7 @@ int main() {
</LanguageSection>
</spoiler>
</Spoiler>
Of course, this wouldn't suffice if the coordinates were up to $10^9$.
@ -103,7 +103,7 @@ This class can often lessen the implementation needed in a lot of bronze problem
For example, here is a nice implementation of the problem ([editorial](http://www.usaco.org/current/data/sol_billboard_bronze_dec17.html)).
<spoiler title="Java Solution With Built-in Rectangle Class">
<Spoiler title="Java Solution With Built-in Rectangle Class">
```java
import java.awt.Rectangle; //needed to use Rectangle class
@ -136,9 +136,9 @@ public class blockedBillboard {
}
}
```
</spoiler>
</Spoiler>
<spoiler title="Java Solution Without Built-in Rectangle Class">
<Spoiler title="Java Solution Without Built-in Rectangle Class">
```java
import java.io.*;
@ -169,7 +169,7 @@ public class blockedBillboard {
}
}
```
</spoiler>
</Spoiler>
</JavaSection>
@ -177,7 +177,7 @@ public class blockedBillboard {
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!). A C++ [`struct`](http://www.cplusplus.com/doc/tutorial/structures/) is the same as a C++ `class` but all members are `public` rather than `private` by default.
<spoiler title="C++ Solution">
<Spoiler title="C++ Solution">
```cpp
#include <bits/stdc++.h>
@ -203,7 +203,7 @@ int main(){
cout << a.area()+b.area()-intersect(a,t)-intersect(b,t) << endl;
}
```
</spoiler>
</Spoiler>
</CPPSection>
@ -212,4 +212,4 @@ int main(){
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -29,9 +29,9 @@ export const metadata = {
}
};
<resources>
<resource source="IUSACO" title="5 - Simulation">module is based off this</resource>
</resources>
<Resources>
<Resource source="IUSACO" title="5 - Simulation">module is based off this</Resource>
</Resources>
<br />
@ -53,7 +53,7 @@ The second line of the input contains $M$, $N$, $P$, and $Q$.
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$.
<spoiler title="Solution">
<Spoiler title="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$.
@ -108,7 +108,7 @@ pw.close(); // flush the output
</LanguageSection>
</spoiler>
</Spoiler>
## Example 2
@ -129,7 +129,7 @@ The third line of the input contains the amount of water in each bucket $A_1, A_
Please print one line of output, containing $N$ space-separated integers: the final amount of water in each bucket once Charlie is done pouring.
<spoiler title="Solution">
<Spoiler title="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$).
@ -180,14 +180,14 @@ pw.close(); // flush the output
</LanguageSection>
</spoiler>
</Spoiler>
## Problems
### Easier
<problems-list problems={metadata.problems.easier} />
<Problems problems={metadata.problems.easier} />
### Harder
<problems-list problems={metadata.problems.harder} />
<Problems problems={metadata.problems.harder} />

View file

@ -1,372 +1,372 @@
---
id: time-comp
title: "Time Complexity"
author: Darren Yao, Benjamin Qi
description: "Evaluating a program's time complexity, or how fast your program runs."
---
<resources>
<resource source="IUSACO" title="3 - Algorithm Analysis">module is based off this</resource>
<resource source="CPH" title="2 - Time Complexity" starred>Intro and examples</resource>
<resource source="PAPS" title="5 - Time Complexity" starred>More in-depth. In particular, 5.2 gives a formal definition of Big O.</resource>
</resources>
<br />
In programming contests, your program needs to finish running within a certain timeframe in order to receive credit. For USACO, this limit is $2$ seconds for C++ submissions, and $4$ seconds for Java/Python submissions. A conservative estimate for the number of <TextTooltip content={`You can think of an "operation" as one instruction for the computer. For example, multiplying two numbers together, reading in a number from the input, or outputting "Hello World" would all be considered "operations." `}>operations</TextTooltip> the grading server can handle per second is $10^8$, but it could be closer to $5 \cdot 10^8$ given good constant factors<Asterisk>If you don't know what constant factors are, don't worry -- we'll explain them below.</Asterisk>.
## Complexity Calculations
We want a method to calculate 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 time 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 constant factors and lower-order terms are generally omitted from $f(n)$. 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.
<LanguageSection>
<CPPSection>
```cpp
int a = 5;
int b = 7;
int c = 4;
int d = a + b + c + 153;
```
</CPPSection>
<JavaSection>
```java
int a = 5;
int b = 7;
int c = 4;
int d = a + b + c + 153;
```
</JavaSection>
<PySection>
```py
a = 5
b = 7
c = 4
d = a + b + c + 153
```
</PySection>
</LanguageSection>
Input and output operations are also assumed to be $O(1)$. In the following examples, we assume that the code inside the loops is $O(1)$.
The time complexity of loops is the number of iterations that the loop runs. For example, the following code examples are both $O(n)$.
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= n; i++) {
// constant time code here
}
```
```cpp
int i = 0;
while (i < n) {
// constant time node here
i++;
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= n; i++) {
// constant time code here
}
```
```java
int i = 0;
while (i < n) {
// constant time node here
i++;
}
```
</JavaSection>
<PySection>
```py
for i in range(1, n+1):
# constant time code here
```
```py
i = 0
while (i < n):
# constant time node here
i += 1
```
</PySection>
</LanguageSection>
Because we ignore constant factors and lower order terms, the following examples are also $O(n)$:
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= 5*n + 17; i++) {
// constant time code here
}
```
```cpp
for (int i = 1; i <= n + 457737; i++) {
// constant time code here
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= 5*n + 17; i++) {
// constant time code here
}
```
```java
for (int i = 1; i <= n + 457737; i++) {
// constant time code here
}
```
</JavaSection>
<PySection>
```py
for i in range(5*n + 17):
# constant time code here
for i in range(n + 457737):
# constant time code here
```
</PySection>
</LanguageSection>
We can find the time complexity of multiple loops by multiplying together the time complexities of each loop. This example is $O(nm)$, because the outer loop runs $O(n)$ iterations and the inner loop $O(m)$.
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// constant time code here
}
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// constant time code here
}
}
```
</JavaSection>
<PySection>
```py
for i in range(n):
for j in range(m):
# constant time code here
```
</PySection>
</LanguageSection>
In this example, the outer loop runs $O(n)$ iterations, and the inner loop runs anywhere between $1$ and $n$ iterations (which is a maximum of $n$). Since Big O notation calculates worst-case time complexity, we treat the inner loop as a factor of $n$.<Asterisk>We can also do some math to calculate exactly how many times the code runs: 1+2+...+n = n*(n-1)/2 = (n^2 - n)/2 = O(n^2)</Asterisk> Thus, this code is $O(n^2)$.
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
// constant time code here
}
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
// constant time code here
}
}
```
</JavaSection>
<PySection>
```py
for i in range(n):
for j in range(i, n):
# constant time code here
```
</PySection>
</LanguageSection>
If an algorithm contains multiple blocks, then its time complexity is the worst time complexity out of any block. For example, the following code is $O(n^2)$.
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
// constant time code here
}
}
for (int i = 1; i <= n + 58834; i++) {
// more constant time code here
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
// constant time code here
}
}
for (int i = 1; i <= n + 58834; i++) {
// more constant time code here
}
```
</JavaSection>
<PySection>
```py
for i in range(n):
for j in range(n):
# constant time code here
for i in range(n + 58834):
# more constant time code here
```
</PySection>
</LanguageSection>
The following code is $O(n^2 + m)$, because it consists of two blocks of complexity $O(n^2)$ and $O(m)$, and neither of them is a lower order function with respect to the other.
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// constant time code here
}
}
for (int i = 1; i <= m; i++) {
// more constant time code here
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// constant time code here
}
}
for (int i = i; j <= m; i++) {
// more constant time code here
}
```
</JavaSection>
<PySection>
```py
for i in range(n):
for j in range(n):
# constant time code here
for i in range(m):
# more constant time code here
```
</PySection>
</LanguageSection>
## Constant Factor
The **constant factor** of an algorithm refers to the coefficient of the complexity of an algorithm. If an algorithm runs in $O(kn)$ time, where $k$ is a constant and $n$ is the input size, then the "constant factor" would be $k$. (Ben - this is not a great definition)
<IncompleteSection />
Normally when using the big-O notation, we ignore the constant factor: $O(3n) = O(n)$. This is fine most of the time, but sometimes we have an algorithm that just barely gets TLE, perhaps by just a few hundred milliseconds. When this happens, it is worth optimizing the constant factor of our algorithm. For example, if our code currently runs in $O(n^2)$ time, perhaps we can modify our code to make it run in $O(n^2/32)$ by using a bitset. (Of course, with big-O notation, $O(n^2) = O(n^2/32)$.)
For now, don't worry about how to optimize constant factors -- just be aware of them.
## Common Complexities and Constraints
Complexity factors that come from some common algorithms and data structures are as follows:
- Mathematical formulas that just calculate an answer: $O(1)$
- Unordered set/map: $O(1)$ per operation
- Binary search: $O(\log n)$
- Ordered set/map or priority queue: $O(\log n)$ per operation
- Prime factorization of an integer, or checking primality or compositeness of an integer naively: $O(\sqrt{n})$
- Reading in $n$ items of input: $O(n)$
- Iterating through an array or a list of $n$ elements: $O(n)$
- Sorting: usually $O(n \log n)$ for default sorting algorithms (mergesort, `Collections.sort`, `Arrays.sort`)
- Java Quicksort `Arrays.sort` function on primitives: $O(n^2)$
- See "Introduction to Data Structures" for details.
- Iterating through all subsets of size $k$ of the input elements: $O(n^k)$. For example, iterating through all triplets is $O(n^3)$.
- Iterating through all subsets: $O(2^n)$
- Iterating through all permutations: $O(n!)$
Here are conservative upper bounds on the value of $n$ for each time complexity. You might get away with more than this, but this should allow you to quickly check whether an algorithm is viable.
<center>
| $n$ | Possible complexities |
| --------------------- | ----------------------------------- |
| $n \le 10$ | $O(n!)$, $O(n^7)$, $O(n^6)$ |
| $n \le 20$ | $O(2^n \cdot n)$, $O(n^5)$ |
| $n \le 80$ | $O(n^4)$ |
| $n \le 400$ | $O(n^3)$ |
| $n \le 7500$ | $O(n^2)$ |
| $n \le 7 \cdot 10^4$ | $O(n \sqrt n)$ |
| $n \le 5 \cdot 10^5$ | $O(n \log n)$ |
| $n \le 5 \cdot 10^6$ | $O(n)$ |
| $n \le 10^{18}$ | $O(\log^2 n)$, $O(\log n)$, $O(1)$ |
</center>
---
id: time-comp
title: "Time Complexity"
author: Darren Yao, Benjamin Qi
description: "Evaluating a program's time complexity, or how fast your program runs."
---
<Resources>
<Resource source="IUSACO" title="3 - Algorithm Analysis">module is based off this</Resource>
<Resource source="CPH" title="2 - Time Complexity" starred>Intro and examples</Resource>
<Resource source="PAPS" title="5 - Time Complexity" starred>More in-depth. In particular, 5.2 gives a formal definition of Big O.</Resource>
</Resources>
<br />
In programming contests, your program needs to finish running within a certain timeframe in order to receive credit. For USACO, this limit is $2$ seconds for C++ submissions, and $4$ seconds for Java/Python submissions. A conservative estimate for the number of <TextTooltip content={`You can think of an "operation" as one instruction for the computer. For example, multiplying two numbers together, reading in a number from the input, or outputting "Hello World" would all be considered "operations." `}>operations</TextTooltip> the grading server can handle per second is $10^8$, but it could be closer to $5 \cdot 10^8$ given good constant factors<Asterisk>If you don't know what constant factors are, don't worry -- we'll explain them below.</Asterisk>.
## Complexity Calculations
We want a method to calculate 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 time 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 constant factors and lower-order terms are generally omitted from $f(n)$. 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.
<LanguageSection>
<CPPSection>
```cpp
int a = 5;
int b = 7;
int c = 4;
int d = a + b + c + 153;
```
</CPPSection>
<JavaSection>
```java
int a = 5;
int b = 7;
int c = 4;
int d = a + b + c + 153;
```
</JavaSection>
<PySection>
```py
a = 5
b = 7
c = 4
d = a + b + c + 153
```
</PySection>
</LanguageSection>
Input and output operations are also assumed to be $O(1)$. In the following examples, we assume that the code inside the loops is $O(1)$.
The time complexity of loops is the number of iterations that the loop runs. For example, the following code examples are both $O(n)$.
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= n; i++) {
// constant time code here
}
```
```cpp
int i = 0;
while (i < n) {
// constant time node here
i++;
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= n; i++) {
// constant time code here
}
```
```java
int i = 0;
while (i < n) {
// constant time node here
i++;
}
```
</JavaSection>
<PySection>
```py
for i in range(1, n+1):
# constant time code here
```
```py
i = 0
while (i < n):
# constant time node here
i += 1
```
</PySection>
</LanguageSection>
Because we ignore constant factors and lower order terms, the following examples are also $O(n)$:
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= 5*n + 17; i++) {
// constant time code here
}
```
```cpp
for (int i = 1; i <= n + 457737; i++) {
// constant time code here
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= 5*n + 17; i++) {
// constant time code here
}
```
```java
for (int i = 1; i <= n + 457737; i++) {
// constant time code here
}
```
</JavaSection>
<PySection>
```py
for i in range(5*n + 17):
# constant time code here
for i in range(n + 457737):
# constant time code here
```
</PySection>
</LanguageSection>
We can find the time complexity of multiple loops by multiplying together the time complexities of each loop. This example is $O(nm)$, because the outer loop runs $O(n)$ iterations and the inner loop $O(m)$.
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// constant time code here
}
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// constant time code here
}
}
```
</JavaSection>
<PySection>
```py
for i in range(n):
for j in range(m):
# constant time code here
```
</PySection>
</LanguageSection>
In this example, the outer loop runs $O(n)$ iterations, and the inner loop runs anywhere between $1$ and $n$ iterations (which is a maximum of $n$). Since Big O notation calculates worst-case time complexity, we treat the inner loop as a factor of $n$.<Asterisk>We can also do some math to calculate exactly how many times the code runs: 1+2+...+n = n*(n-1)/2 = (n^2 - n)/2 = O(n^2)</Asterisk> Thus, this code is $O(n^2)$.
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
// constant time code here
}
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
// constant time code here
}
}
```
</JavaSection>
<PySection>
```py
for i in range(n):
for j in range(i, n):
# constant time code here
```
</PySection>
</LanguageSection>
If an algorithm contains multiple blocks, then its time complexity is the worst time complexity out of any block. For example, the following code is $O(n^2)$.
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
// constant time code here
}
}
for (int i = 1; i <= n + 58834; i++) {
// more constant time code here
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
// constant time code here
}
}
for (int i = 1; i <= n + 58834; i++) {
// more constant time code here
}
```
</JavaSection>
<PySection>
```py
for i in range(n):
for j in range(n):
# constant time code here
for i in range(n + 58834):
# more constant time code here
```
</PySection>
</LanguageSection>
The following code is $O(n^2 + m)$, because it consists of two blocks of complexity $O(n^2)$ and $O(m)$, and neither of them is a lower order function with respect to the other.
<LanguageSection>
<CPPSection>
```cpp
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// constant time code here
}
}
for (int i = 1; i <= m; i++) {
// more constant time code here
}
```
</CPPSection>
<JavaSection>
```java
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// constant time code here
}
}
for (int i = i; j <= m; i++) {
// more constant time code here
}
```
</JavaSection>
<PySection>
```py
for i in range(n):
for j in range(n):
# constant time code here
for i in range(m):
# more constant time code here
```
</PySection>
</LanguageSection>
## Constant Factor
The **constant factor** of an algorithm refers to the coefficient of the complexity of an algorithm. If an algorithm runs in $O(kn)$ time, where $k$ is a constant and $n$ is the input size, then the "constant factor" would be $k$. (Ben - this is not a great definition)
<IncompleteSection />
Normally when using the big-O notation, we ignore the constant factor: $O(3n) = O(n)$. This is fine most of the time, but sometimes we have an algorithm that just barely gets TLE, perhaps by just a few hundred milliseconds. When this happens, it is worth optimizing the constant factor of our algorithm. For example, if our code currently runs in $O(n^2)$ time, perhaps we can modify our code to make it run in $O(n^2/32)$ by using a bitset. (Of course, with big-O notation, $O(n^2) = O(n^2/32)$.)
For now, don't worry about how to optimize constant factors -- just be aware of them.
## Common Complexities and Constraints
Complexity factors that come from some common algorithms and data structures are as follows:
- Mathematical formulas that just calculate an answer: $O(1)$
- Unordered set/map: $O(1)$ per operation
- Binary search: $O(\log n)$
- Ordered set/map or priority queue: $O(\log n)$ per operation
- Prime factorization of an integer, or checking primality or compositeness of an integer naively: $O(\sqrt{n})$
- Reading in $n$ items of input: $O(n)$
- Iterating through an array or a list of $n$ elements: $O(n)$
- Sorting: usually $O(n \log n)$ for default sorting algorithms (mergesort, `Collections.sort`, `Arrays.sort`)
- Java Quicksort `Arrays.sort` function on primitives: $O(n^2)$
- See "Introduction to Data Structures" for details.
- Iterating through all subsets of size $k$ of the input elements: $O(n^k)$. For example, iterating through all triplets is $O(n^3)$.
- Iterating through all subsets: $O(2^n)$
- Iterating through all permutations: $O(n!)$
Here are conservative upper bounds on the value of $n$ for each time complexity. You might get away with more than this, but this should allow you to quickly check whether an algorithm is viable.
<center>
| $n$ | Possible complexities |
| --------------------- | ----------------------------------- |
| $n \le 10$ | $O(n!)$, $O(n^7)$, $O(n^6)$ |
| $n \le 20$ | $O(2^n \cdot n)$, $O(n^5)$ |
| $n \le 80$ | $O(n^4)$ |
| $n \le 400$ | $O(n^3)$ |
| $n \le 7500$ | $O(n^2)$ |
| $n \le 7 \cdot 10^4$ | $O(n \sqrt n)$ |
| $n \le 5 \cdot 10^5$ | $O(n \log n)$ |
| $n \le 5 \cdot 10^6$ | $O(n)$ |
| $n \le 10^{18}$ | $O(\log^2 n)$, $O(\log n)$, $O(1)$ |
</center>

View file

@ -26,9 +26,9 @@ export const metadata = {
}
};
<resources>
<resource source="IUSACO" title="4.3 - Sets & Maps">module is based off this</resource>
</resources>
<Resources>
<Resource source="IUSACO" title="4.3 - Sets & Maps">module is based off this</Resource>
</Resources>
## What Are Sets and Maps?
@ -46,7 +46,7 @@ Both Java and C++ contain two versions of sets and maps; one in which the keys a
## Sets
<problems-list problems={metadata.problems.dis} />
<Problems problems={metadata.problems.dis} />
<LanguageSection>
@ -105,7 +105,7 @@ for(int element : set){
## Maps
<problems-list problems={metadata.problems.ex} />
<Problems problems={metadata.problems.ex} />
<LanguageSection>
@ -153,9 +153,9 @@ System.out.println(map.containsKey(1)); // true
<CPPSection>
<resources>
<resource source="Mark Nelson" title="Hash Functions for C++ Unordered Containers" url="https://marknelson.us/posts/2011/09/03/hash-functions-for-c-unordered-containers.html" starred>How to create user-defined hash function for `unordered_map`.</resource>
</resources>
<Resources>
<Resource source="Mark Nelson" title="Hash Functions for C++ Unordered Containers" url="https://marknelson.us/posts/2011/09/03/hash-functions-for-c-unordered-containers.html" starred>How to create user-defined hash function for `unordered_map`.</Resource>
</Resources>
The link provides an example of hashing pairs of strings. More examples (for pairs of ints)
@ -205,11 +205,11 @@ However, this hash function is quite bad; if we insert $(0,0), (1,1), (2,2) \ldo
## Hacking
<warning-block>
<Warning>
You don't need to know this for USACO, but you will need this to pass some of the problems in this module.
</warning-block>
</Warning>
In USACO contests, unordered sets and maps generally fine, but the built-in hashing algorithm for C++ is vulnerable to pathological data sets causing abnormally slow runtimes. Apparently [Java](https://codeforces.com/blog/entry/62393?#comment-464875) is not vulnerable to this, however.
@ -217,17 +217,17 @@ In USACO contests, unordered sets and maps generally fine, but the built-in hash
<CPPSection>
<resources>
<resource title="Blowing up Unordered Map" source="CF" url="blog/entry/62393" starred>Explanation of this problem and how to fix it.</resource>
</resources>
<Resources>
<Resource title="Blowing up Unordered Map" source="CF" url="blog/entry/62393" starred>Explanation of this problem and how to fix it.</Resource>
</Resources>
Essentially use `unordered_map<int, int, custom_hash>` defined in the blog above in place of `unordered_map<int, int>`.
### Another Hash Function
<resources>
<resource source="Benq (from KACTL)" title="HashMap" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/STL%20(5)/HashMap.h" starred> </resource>
</resources>
<Resources>
<Resource source="Benq (from KACTL)" title="HashMap" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/STL%20(5)/HashMap.h" starred> </Resource>
</Resources>
```cpp
struct chash { /// use most bits rather than just the lowest ones
@ -251,4 +251,4 @@ Mentioned in several of the links above. See Gold for dtails.
## Problems
<problems-list problems={metadata.problems.standard} />
<Problems problems={metadata.problems.standard} />

View file

@ -1,72 +0,0 @@
---
id: ad-hoc
title: Approaching Ad Hoc Problems
author: Michael Cao
description: "Tips on Ad Hoc problems (problems with no clear category) in the Bronze Division."
frequency: 2
---
import { Problem } from "../models";
export const metadata = {
problems: {
general: [
new Problem("Bronze", "Cow Tipping", "689", "Hard", false, [], "Cells in the last row and column can be toggled uniquely. Toggle the appropriate ones and then recurse to the rectangle in the previous row/column, and solve the same way."),
new Problem("Bronze", "Race", "989", "Very Hard", false, [], "Greedily increment/decrement Bessies speed to fit the conditions until her total distance exceeds K."),
],
greedyTutorial: [
new Problem("Bronze", "Mad Scientist", "1012", "Normal", false, [], ""),
]
}
};
Some bronze problems don't fall into any specific category, such as compete search or rectangle geometry, and often require more thought while also being easier to implement. Any problem that doesn't fall under any well-defined category can be labelled as **Ad Hoc**.
Since Ad Hoc problems don't fall under any specific category, they can be hard to generalize, so there is no fixed algorithm or idea to solving these problems. In this module, we'll go over some general tips that may be useful in approaching these problems and present some practice problems.
## Tips for Approaching Ad Hoc Problems
<ul>
<li> Draw lots of small cases to gain a better understanding of the problem. If you're having trouble debugging, draw more cases. If you don't know how to start with a problem, draw more cases. Whenever you don't know how to further approach a problem, you're probably missing an important observation, so draw more cases and make observations about properties of the problem. </li>
<li> Whenever you find an observation that seems useful, write it down! Writing down ideas lets you easily come back to them later, and makes sure you don't forget about ideas that could potentially be the solution. </li>
<li> Don't get stuck on any specific idea, unless you see an entire solution. Trying to complete search an Ad Hoc problem will just end up wasting a lot of your time in contest. </li>
<li> Try to approach the problem from a lot of different perspectives. Try to draw a visual depiction of the problem, mess around with formulas, or model it as a Graph Theory problem (see Graph Theory module). One of the most helpful things you can do when solving Ad Hoc problems is to keep trying ideas until you make progress. This is something you get better at as you do more problems.</li>
</ul>
These tips are helpful in solving Ad Hoc problems. However, in the end, the best way to get better at Ad Hoc problems (or any type of problems) is to do a lot of them. Try to solve as many practice problems below as you can, and click the solution sketch tab if you can't figure the solution out.
## Greedy Problems
One thing to note about Ad Hoc problems in the USACO Bronze division is that many of them, while difficult to categorize into specific algorithms or data structures, can be solved using **Greedy** techniques. While this idea will be covered more in future [modules](https://usaco-guide.netlify.app/silver/greedy), we'll introduce the general mindset in this section.
When approaching a greedy problem, we want to make argument about the structure of the solution of the problem. Specifically, that certain "greedy" actions, or actions that create the best possible solution at some local point in the algorithm, will lead to an optimal solution at the end.
Consider some possible greedy algorithms for the USACO Bronze problem "Mad Scientist."
<problem-list problems={metadata.problems.greedyTutorial} />
<spoiler title="Correct Greedy Algorithm">
In this problem, the correct greedy solution is to continually flip the longest possible ranges of mismatching cows.
Mad Scientist has an excellent [editorial](http://www.usaco.org/current/data/sol_breedflip_bronze_feb20.html) with a video solution and intuitive proof.
It is highly recommended you read it to gain a better understanding of the greedy algorithm.
</spoiler>
However, not all greedy problems in the bronze division necessarily require mathematical proofs of correctness. It is often sufficent to intuitively convince yourself your algorithm is correct.
<info-block title="Pro Tip">
Sometimes, if the algorithm is easy enough to implement, you don't even need to convince yourself it's correct: just let the online judge prove it for you by coding it and seeing if it passes. Competitive programmers refer to this as "Proof by AC," or "Proof by Accepted."
<!-- Don't overuse it though? -->
</info-block>
<problems-list problems={metadata.problems.general} />
<IncompleteSection>
</IncompleteSection>
<!-- Anything else major that needs to be added? Bronze Ad Hoc is not very complicated. -->

View file

@ -36,9 +36,9 @@ export const metadata = {
}
};
<resources>
<resource source="IUSACO" title="12 - Binary Search">module is based off this</resource>
</resources>
<Resources>
<Resource source="IUSACO" title="12 - Binary Search">module is based off this</Resource>
</Resources>
<br />
@ -152,7 +152,7 @@ static long search(){
## Example: Maximum Median
<problems-list problems={metadata.problems.ex} />
<Problems problems={metadata.problems.ex} />
**Statement:** Given an array $\texttt{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.
@ -259,8 +259,8 @@ static boolean check(long x){
## USACO Problems
<problems-list problems={metadata.problems.usaco} />
<Problems problems={metadata.problems.usaco} />
## General Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -24,13 +24,13 @@ export const metadata = {
Suppose that we want to find an element in a sorted array of size $N$ in $O(\log N)$ time. We can do this with [**binary search**](https://en.wikipedia.org/wiki/Binary_search_algorithm); 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 every element in an array.
<resources>
<resource source="KA" title="Binary Search" url="https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/binary-search" starred>animations!</resource>
<resource source="CSA" title="Binary Search" url="binary_search" starred>animation!</resource>
<resource source="CPH" title="3.3 - Binary Search" starred></resource>
<resource source="TC" title="Binary Search" url="binary-search"></resource>
<resource source="GFG" title="Binary Search" url="binary-search"></resource>
</resources>
<Resources>
<Resource source="KA" title="Binary Search" url="https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/binary-search" starred>animations!</Resource>
<Resource source="CSA" title="Binary Search" url="binary_search" starred>animation!</Resource>
<Resource source="CPH" title="3.3 - Binary Search" starred></Resource>
<Resource source="TC" title="Binary Search" url="binary-search"></Resource>
<Resource source="GFG" title="Binary Search" url="binary-search"></Resource>
</Resources>
## Library Functions
@ -38,19 +38,19 @@ Suppose that we want to find an element in a sorted array of size $N$ in $O(\log
<CPPSection>
<resources>
<resource source="CPP" url="http://www.cplusplus.com/reference/algorithm/lower_bound/" title="lower_bound"> </resource>
<resource source="CPP" url="http://www.cplusplus.com/reference/algorithm/upper_bound/" title="upper_bound"> </resource>
</resources>
<Resources>
<Resource source="CPP" url="http://www.cplusplus.com/reference/algorithm/lower_bound/" title="lower_bound"> </Resource>
<Resource source="CPP" url="http://www.cplusplus.com/reference/algorithm/upper_bound/" title="upper_bound"> </Resource>
</Resources>
</CPPSection>
<JavaSection>
<resources>
<resource source="JAVA" url="https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#binarySearch(int[],%20int)" title="Arrays.binarySearch"> </resource>
<resource source="JAVA" url="https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#binarySearch(java.util.List,%20T)" title="Collections.binarySearch"> </resource>
</resources>
<Resources>
<Resource source="JAVA" url="https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#binarySearch(int[],%20int)" title="Arrays.binarySearch"> </Resource>
<Resource source="JAVA" url="https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#binarySearch(java.util.List,%20T)" title="Collections.binarySearch"> </Resource>
</Resources>
</JavaSection>
@ -60,13 +60,13 @@ Suppose that we want to find an element in a sorted array of size $N$ in $O(\log
A related topic is **coordinate compression**, which takes some points and reassigns them to remove wasted space.
<problems-list problems={metadata.problems.count} />
<Problems problems={metadata.problems.count} />
> 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.
<spoiler title="Solution">
<Spoiler title="Solution">
Let's place all of the locations of the haybales into a list and sort it.
@ -79,4 +79,4 @@ Let's place all of the locations of the haybales into a list and sort it.
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.
-->
</spoiler>
</Spoiler>

View file

@ -9,9 +9,9 @@ description: "?"
frequency: 1
---
<resources>
<resource source="fushar" title="Comparison Functions in C++" starred url="http://fusharblog.com/3-ways-to-define-comparison-functions-in-cpp/">Covers all of this material.</resource>
</resources>
<Resources>
<Resource source="fushar" title="Comparison Functions in C++" starred url="http://fusharblog.com/3-ways-to-define-comparison-functions-in-cpp/">Covers all of this material.</Resource>
</Resources>
<br />

View file

@ -51,19 +51,19 @@ export const metadata = {
## Resources
<resources>
<resource source="CPH" title="12.1 - DFS, 14 - Tree algorithms" starred></resource>
<resource source="CSA" title="Depth First Search" url="depth_first_search" starred>interactive</resource>
<resource source="IUSACO" title="10.4 - Graph Traversal Algorithms"></resource>
<resource source="PAPS" title="12.2 - Depth-First Search">with an example problem</resource>
<resource source="CPC" title="7 - Graphs 1" url="07_graphs_1">fast-paced</resource>
<resource source="cp-algo" title="Depth First Search" url="graph/depth-first-search.html">hard to parse for a beginner</resource>
<resource source="TC" title="Graphs Section 2" url="introduction-to-graphs-and-their-data-structures-section-2"></resource>
</resources>
<Resources>
<Resource source="CPH" title="12.1 - DFS, 14 - Tree algorithms" starred></Resource>
<Resource source="CSA" title="Depth First Search" url="depth_first_search" starred>interactive</Resource>
<Resource source="IUSACO" title="10.4 - Graph Traversal Algorithms"></Resource>
<Resource source="PAPS" title="12.2 - Depth-First Search">with an example problem</Resource>
<Resource source="CPC" title="7 - Graphs 1" url="07_graphs_1">fast-paced</Resource>
<Resource source="cp-algo" title="Depth First Search" url="graph/depth-first-search.html">hard to parse for a beginner</Resource>
<Resource source="TC" title="Graphs Section 2" url="introduction-to-graphs-and-their-data-structures-section-2"></Resource>
</Resources>
## Counting Connected Components
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
### Implementation
@ -73,7 +73,7 @@ export const metadata = {
### Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
## Tree Problems
@ -85,22 +85,22 @@ export const metadata = {
### Problems
<problems-list problems={metadata.problems.tree} />
<Problems problems={metadata.problems.tree} />
## Graph Two-Coloring
*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.
<problems-list problems={metadata.problems.bipsample} />
<Problems problems={metadata.problems.bipsample} />
### Resources
<resources>
<resource source="IUSACO" title="10.7 - Bipartite Graphs" starred></resource>
<resource source="CPH" title="12.3 - Graph Traversal: Applications"></resource>
<resource source="cp-algo" title="Bipartite Check" url="graph/bipartite-check.html">Uses BFS, but DFS accomplishes the same task.</resource>
</resources>
<Resources>
<Resource source="IUSACO" title="10.7 - Bipartite Graphs" starred></Resource>
<Resource source="CPH" title="12.3 - Graph Traversal: Applications"></Resource>
<Resource source="cp-algo" title="Bipartite Check" url="graph/bipartite-check.html">Uses BFS, but DFS accomplishes the same task.</Resource>
</Resources>
### Implementation
@ -138,4 +138,4 @@ void dfs(int node)
### Problems
<problems-list problems={metadata.problems.bip} />
<Problems problems={metadata.problems.bip} />

View file

@ -32,13 +32,13 @@ export const metadata = {
}
};
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
<br />
<resources>
<resource source="IUSACO" title="10.5 - Flood Fill">module is based off this</resource>
</resources>
<Resources>
<Resource source="IUSACO" title="10.5 - Flood Fill">module is based off this</Resource>
</Resources>
**Flood fill** is an algorithm that identifies and labels the connected component that a
particular cell belongs to, in a multi-dimensional array. Essentially, its DFS, but on a grid,
@ -104,9 +104,9 @@ int main(){
## Implementation
<resources>
<resource source="GFG" title="Flood Fill" url="flood-fill-algorithm-implement-fill-paint"></resource>
</resources>
<Resources>
<Resource source="GFG" title="Flood Fill" url="flood-fill-algorithm-implement-fill-paint"></Resource>
</Resources>
When doing floodfill, we will maintain an $N\times M$ array of booleans to keep track of
which squares have been visited, and a global variable to maintain the size of the current
@ -208,4 +208,4 @@ static void floodfill(int r, int c, int color){
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -29,15 +29,15 @@ export const metadata = {
We'll consider graphs like the one presented in this problem:
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
< br/>
Aka **successor graph**.
<resources>
<resource source="CPH" title="16.3, 16.4 - Successor Graphs"></resource>
</resources>
<Resources>
<Resource source="CPH" title="16.3, 16.4 - Successor Graphs"></Resource>
</Resources>
## Implementation
@ -83,4 +83,4 @@ int main()
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -3,9 +3,10 @@ id: greedy
title: "Greedy Algorithms"
author: Darren Yao
prerequisites:
- intro-greedy
- sorting-custom
- intro-ordered
description: "Greedily selecting the optimal choice at each step in your algorithm instead of looking at the solution space as a whole."
description: "Continuation of greedy problems that were introduced in Bronze."
frequency: 3
---
@ -43,83 +44,28 @@ export const metadata = {
}
};
<resources>
<resource source="IUSACO" title="9 - Greedy Algorithms" starred>Module is based off this.</resource>
<resource source="CPH" title="6 - Greedy Algorithms" starred></resource>
<resource source="PAPS" title="8 - Greedy Algorithms"></resource>
<resource source="CPC" title="5 - Greedy Algorithms" url="05_greedy_algorithms"></resource>
</resources>
<Resources>
<Resource source="IUSACO" title="9 - Greedy Algorithms">Module is based off this.</Resource>
<Resource source="CPH" title="6 - Greedy Algorithms" starred></Resource>
<Resource source="PAPS" title="8 - Greedy Algorithms"></Resource>
<Resource source="CPC" title="5 - Greedy Algorithms" url="05_greedy_algorithms"></Resource>
</Resources>
<br />
**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. Here, we'll focus on problems where some sorting step is involved.
Usually, when using a greedy algorithm, there is a **heuristic** or **value function** that determines which choice is considered most optimal.
(what's a heuristic or value function?)
<IncompleteSection />
## Example: Studying Algorithms
Here, we'll focus on problems where some sorting step is involved.
### Statement
## Example: The Scheduling Problem
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.
<Problems problems={metadata.problems.movie} />
### 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)$.
<LanguageSection>
<CPPSection>
```cpp
// read in the input, store the algorithms in a vector, algorithms
sort(algorithms.begin(), algorithms.end());
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++;
}
cout << i << endl; // print the ans
```
</CPPSection>
<JavaSection>
```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();
```
</JavaSection>
</LanguageSection>
## The Scheduling Problem
<problems-list problems={metadata.problems.movie} />
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.
There are $N$ events, each described by their starting and ending times. You can only attend one event at a time, and if you choose to attend an event, you must attend the entire event. Traveling between events is instantaneous. What's the maximum number of events you can attend?
### Bad Greedy: Earliest Starting Next Event
@ -228,41 +174,14 @@ pw.close();
</LanguageSection>
## 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:
<center>
| Item | Weight | Value | Value Per Weight |
|------|--------|-------|------------------|
| A | 3 | 18 | 6 |
| B | 2 | 10 | 5 |
| C | 2 | 10 | 5 |
</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.
## CSES Problems
<problems-list problems={metadata.problems.cses} />
<Problems problems={metadata.problems.cses} />
## USACO Problems
<problems-list problems={metadata.problems.usaco} />
<Problems problems={metadata.problems.usaco} />
## Other Problems
<problems-list problems={metadata.problems.other} />
<Problems problems={metadata.problems.other} />

View file

@ -30,9 +30,9 @@ export const metadata = {
## Example: Using Iterators
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
<spoiler title="Solution">
<Spoiler title="Solution">
```cpp
#include <bits/stdc++.h>
@ -123,10 +123,10 @@ int main() {
}
```
</spoiler>
</Spoiler>
<IncompleteSection />
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -19,10 +19,10 @@ export const metadata = {
}
};
<resources>
<resource source="IUSACO" title="4.3 - Sets & Maps">module is based off this</resource>
<resource source="CPH" title="4.2 to 4.4 - Data Structures" starred>sets, maps, set iterators</resource>
</resources>
<Resources>
<Resource source="IUSACO" title="4.3 - Sets & Maps">module is based off this</Resource>
<Resource source="CPH" title="4.2 to 4.4 - Data Structures" starred>sets, maps, set iterators</Resource>
</Resources>
<br />
@ -212,4 +212,4 @@ next(), prev(), ++, --
## Standard
<problems-list problems={metadata.problems.standard} />
<Problems problems={metadata.problems.standard} />

View file

@ -50,15 +50,15 @@ export const metadata = {
};
<resources title="Additional">
<resource source="IUSACO" title="11 - Prefix Sums" starred>module is based off this</resource>
<resource source="CPH" title="9.1 - Sum Queries">rather brief</resource>
<resource source="PAPS" title="11.2.1 - Prefix Precomputation">also rather brief</resource>
</resources>
<Resources title="Additional">
<Resource source="IUSACO" title="11 - Prefix Sums" starred>module is based off this</Resource>
<Resource source="CPH" title="9.1 - Sum Queries">rather brief</Resource>
<Resource source="PAPS" title="11.2.1 - Prefix Precomputation">also rather brief</Resource>
</Resources>
## Introduction
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
Let's say we have a one-indexed integer array $\texttt{arr}$ of size $N$ and we want to compute the value of
$$
@ -205,31 +205,31 @@ These are also known as [partial sums](https://mathworld.wolfram.com/PartialSum.
### Problems
<problems-list problems={metadata.problems.cum} />
<Problems problems={metadata.problems.cum} />
## Max Subarray Sum
Now we'll look at some extensions.
<problems-list problems={metadata.problems.maxsum} />
<Problems problems={metadata.problems.maxsum} />
This problem has a solution known as [Kadane's Algorithm](https://en.wikipedia.org/wiki/Maximum_subarray_problem#Kadane's_algorithm). Please don't use that solution; try to solve it with prefix sums.
<spoiler title="Why are the two methods equivalent?">
<Spoiler title="Why are the two methods equivalent?">
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.
</spoiler>
</Spoiler>
## 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.
<problems-list problems={metadata.problems.related} />
<Problems problems={metadata.problems.related} />
## 2D Prefix Sums
<problems-list problems={metadata.problems.sample2} />
<Problems problems={metadata.problems.sample2} />
Now, what if we wanted to process $Q$ queries for the sum over a subrectangle of a $N$ rows by $M$ columns matrix in two dimensions? Let's assume both rows and columns are 1-indexed, and we use the following matrix as an example:
@ -474,7 +474,7 @@ as expected.
Since no matter the size of the submatrix we are summing, we only need to access four values of the 2D prefix sum array, this runs in $O(1)$ per query after an $O(NM)$ preprocessing.
<problems-list problems={metadata.problems.cum2} />
<Problems problems={metadata.problems.cum2} />
## More Complex Applications
@ -507,4 +507,4 @@ $$
Which is what we were looking for!
<problems-list problems={metadata.problems.complex} />
<Problems problems={metadata.problems.complex} />

View file

@ -44,14 +44,14 @@ export const metadata = {
## Two Pointers
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
Two pointers refers to iterating two monotonic pointers across an array to search for a pair of indices satisfying some condition in linear time.
<resources>
<resource source="CPH" title="8.1 - Two Pointers"></resource>
<resource source="IUSACO" title="14.1 - Two Pointers"></resource>
</resources>
<Resources>
<Resource source="CPH" title="8.1 - Two Pointers"></Resource>
<Resource source="IUSACO" title="14.1 - Two Pointers"></Resource>
</Resources>
### Implementation
@ -59,7 +59,7 @@ Two pointers refers to iterating two monotonic pointers across an array to searc
## Sliding Window
<problems-list problems={metadata.problems.slide} />
<Problems problems={metadata.problems.slide} />
Let's envision a **sliding window** (or constant size subarray) of size $K$ moving left to right along an array, $a$.
@ -67,10 +67,10 @@ For each position of the window, we want to compute some information. For exampl
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 subtracting $a_i$ from $s$ and adding $a_{j+1}$ to $s$.
<resources>
<resource source="Medium" title="Introduction to Sliding Window Algorithms" url="https://levelup.gitconnected.com/an-introduction-to-sliding-window-algorithms-5533c4fe1cc7"> </resource>
<resource source="GFG" title="Window Sliding Technique" url="window-sliding-technique"> </resource>
</resources>
<Resources>
<Resource source="Medium" title="Introduction to Sliding Window Algorithms" url="https://levelup.gitconnected.com/an-introduction-to-sliding-window-algorithms-5533c4fe1cc7"> </Resource>
<Resource source="GFG" title="Window Sliding Technique" url="window-sliding-technique"> </Resource>
</Resources>
### Implementation
@ -78,14 +78,14 @@ To compute the sum in the range, instead of using a set, we can store a variable
### Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
## Sliding Window Minimum in $O(N)$
<resources>
<resource source="cp-algo" title="Minimum stack / Minimum queue" url="data_structures/stack_queue_modification.html" starred>Mentions two ways to solve this (both are important)!</resource>
</resources>
<Resources>
<Resource source="cp-algo" title="Minimum stack / Minimum queue" url="data_structures/stack_queue_modification.html" starred>Mentions two ways to solve this (both are important)!</Resource>
</Resources>
In particular, the second method allows us to solve the following generalization in linear time as well:
<problems-list problems={metadata.problems.qs} />
<Problems problems={metadata.problems.qs} />

View file

@ -214,4 +214,4 @@ Comments: Comparator 1 sorts array $a$ in decreasing order. Comparator 2 sorts a
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -26,15 +26,15 @@ export const metadata = {
}
};
<resources>
<resource source="IUSACO" title="8 - Sorting & Comparators"></resource>
</resources>
<Resources>
<Resource source="IUSACO" title="8 - Sorting & Comparators"></Resource>
</Resources>
<br />
## Example: Wormhole Sort
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
There are multiple ways to solve this problem. We won't discuss the full solution here, but all of them start by sorting the edges in nondecreasing order of weight. For example, the sample contains the following edges:
@ -187,9 +187,9 @@ Normally, sorting functions rely on moving objects with a lower value in front o
<CPPSection>
<resources>
<resource source="CPH" title="3.2 - User-Defined Structs, Comparison Functions" starred></resource>
</resources>
<Resources>
<Resource source="CPH" title="3.2 - User-Defined Structs, Comparison Functions" starred></Resource>
</Resources>
What a comparator does is compare two objects as follows, based on our comparison criteria:
@ -571,4 +571,4 @@ public class Sol {
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -18,9 +18,9 @@ export const metadata = {
}
};
<resources>
<resource source="CPH" title="3.1 - Sorting Theory" starred>types of sorting</resource>
</resources>
<Resources>
<Resource source="CPH" title="3.1 - Sorting Theory" starred>types of sorting</Resource>
</Resources>
<br />
@ -32,7 +32,7 @@ There are many sorting algorithms, here are some sources to learn about the popu
## Bubble Sort
<problems-list problems={metadata.problems.bubble} />
<Problems problems={metadata.problems.bubble} />
### Tutorial

View file

@ -28,7 +28,7 @@ export const metadata = {
## Example: Wormhole Sort
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
There are multiple ways to solve this problem. We won't discuss the full solution here, but all of them start by sorting the edges in nondecreasing order of weight.
@ -90,9 +90,9 @@ Normally, sorting functions rely on moving objects with a lower value in front o
### C++
<resources>
<resource source="CPH" title="3.2 - User-Defined Structs, Comparison Functions" starred></resource>
</resources>
<Resources>
<Resource source="CPH" title="3.2 - User-Defined Structs, Comparison Functions" starred></Resource>
</Resources>
What a comparator does is compare two objects as follows, based on our comparison criteria:
@ -123,9 +123,9 @@ Java has default functions for comparing `int`, `long`, `double` types. The `Int
## C++
<resources>
<resource source="fushar" title="Comparison Functions in C++" url="http://fusharblog.com/3-ways-to-define-comparison-functions-in-cpp/"></resource>
</resources>
<Resources>
<Resource source="fushar" title="Comparison Functions in C++" url="http://fusharblog.com/3-ways-to-define-comparison-functions-in-cpp/"></Resource>
</Resources>
### Method 1: Operator <

View file

@ -24,12 +24,12 @@ export const metadata = {
## Additional Reading
<resources>
<resource source="CPH" title="4.5 - Stacks, Queues, Priority Queues"></resource>
<resource source="PAPS" title="3.2 to 3.4 - C++ STL"></resource>
<resource source="PAPS" title="6.2, 6.3, 6.5 - Stacks, Queues, Priority Queues"></resource>
<resource source="CP1" title="2.2 - Data Structures with Built-in Libraries"> </resource>
</resources>
<Resources>
<Resource source="CPH" title="4.5 - Stacks, Queues, Priority Queues"></Resource>
<Resource source="PAPS" title="3.2 to 3.4 - C++ STL"></Resource>
<Resource source="PAPS" title="6.2, 6.3, 6.5 - Stacks, Queues, Priority Queues"></Resource>
<Resource source="CP1" title="2.2 - Data Structures with Built-in Libraries"> </Resource>
</Resources>
## Stacks
@ -222,7 +222,7 @@ pq.add(6); // [7, 6, 5]
## Monotonic Stack
<problems-list problems={metadata.problems.nearest} />
<Problems problems={metadata.problems.nearest} />
Consider the following problem:
@ -241,14 +241,14 @@ The stack we used is called a **monotonic stack** because we keep popping off th
### Further Reading
<resources>
<resource source="CPH" title="8.2 - Nearest Smaller Element"></resource>
<resource source="Medium" title="Monotonic Stack" url="https://medium.com/@vishnuvardhan623/monotonic-stack-e9dcc4fa8c3e"></resource>
</resources>
<Resources>
<Resource source="CPH" title="8.2 - Nearest Smaller Element"></Resource>
<Resource source="Medium" title="Monotonic Stack" url="https://medium.com/@vishnuvardhan623/monotonic-stack-e9dcc4fa8c3e"></Resource>
</Resources>
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
<!--

View file

@ -25,19 +25,19 @@ export const metadata = {
}
};
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
## Resources
<resources>
<resource source="CSA" title="Breadth First Search" url="breadth_first_search" starred>interactive</resource>
<resource source="CPH" title="12.2 - Breadth-First Search" starred></resource>
<resource source="PAPS" title="12.1 - Breadth-First Search"></resource>
<resource source="KA" title="Breadth First Search and Its Uses" url="https://www.khanacademy.org/computing/computer-science/algorithms/breadth-first-search/a/breadth-first-search-and-its-uses"></resource>
<resource source="cp-algo" title="Breadth First Search" url="graph/breadth-first-search.html"></resource>
<resource source="cp-algo" title="0/1 BFS" url="graph/01_bfs.html"></resource>
<resource source="IUSACO" title="10.4 - Graph Traversal Algorithms"></resource>
</resources>
<Resources>
<Resource source="CSA" title="Breadth First Search" url="breadth_first_search" starred>interactive</Resource>
<Resource source="CPH" title="12.2 - Breadth-First Search" starred></Resource>
<Resource source="PAPS" title="12.1 - Breadth-First Search"></Resource>
<Resource source="KA" title="Breadth First Search and Its Uses" url="https://www.khanacademy.org/computing/computer-science/algorithms/breadth-first-search/a/breadth-first-search-and-its-uses"></Resource>
<Resource source="cp-algo" title="Breadth First Search" url="graph/breadth-first-search.html"></Resource>
<Resource source="cp-algo" title="0/1 BFS" url="graph/01_bfs.html"></Resource>
<Resource source="IUSACO" title="10.4 - Graph Traversal Algorithms"></Resource>
</Resources>
## Implementation
@ -45,4 +45,4 @@ export const metadata = {
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -29,19 +29,19 @@ export const metadata = {
## Undirected Graphs
<problems-list problems={metadata.problems.und} />
<Problems problems={metadata.problems.und} />
(explanation?)
<optional-content title="+1 Approximation for Shortest Cycle">
<Optional title="+1 Approximation for Shortest Cycle">
An algorithm known as **BFS-Cycle** returns an integer that is at most one more than the length of the shortest cycle in $O(N^2)$ time; see page 4 [here](https://people.csail.mit.edu/virgi/6.890/lecture9.pdf) for details.
</optional-content>
</Optional>
## Directed Graphs
<problems-list problems={metadata.problems.dir} />
<Problems problems={metadata.problems.dir} />
The same general idea is implemented below to find any cycle in a directed graph (if one exists). Note that this is almost identical to the DFS algorithm for topological sorting.
@ -107,6 +107,6 @@ int main()
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
VT-HSPC 2019?

View file

@ -58,49 +58,49 @@ Dynamic Programming is an important algorithmic technique in competitive program
The following tutorials serve as an introduction into the mindset of DP.
<resources>
<resource source="CPH" title="7 - DP" starred>Great introduction that covers most classical problems. Mentions memoization.</resource>
<resource source="TC" title="DP from Novice to Advanced" url="dynamic-programming-from-novice-to-advanced">great for all skill levels</resource>
<resource source="CPC" title="6 - DP" url="06_dynamic_programming">examples with nonclassical problems</resource>
<resource source="HR" title="DP" url="https://www.hackerrank.com/topics/dynamic-programming">also covers many classical problems</resource>
<resource source="PAPS" title="9 - DP">starts with DAGs, which are covered in "Topological Sort"</resource>
</resources>
<Resources>
<Resource source="CPH" title="7 - DP" starred>Great introduction that covers most classical problems. Mentions memoization.</Resource>
<Resource source="TC" title="DP from Novice to Advanced" url="dynamic-programming-from-novice-to-advanced">great for all skill levels</Resource>
<Resource source="CPC" title="6 - DP" url="06_dynamic_programming">examples with nonclassical problems</Resource>
<Resource source="HR" title="DP" url="https://www.hackerrank.com/topics/dynamic-programming">also covers many classical problems</Resource>
<Resource source="PAPS" title="9 - DP">starts with DAGs, which are covered in "Topological Sort"</Resource>
</Resources>
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.
<info-block title="Pro Tip">
<Info title="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)$).
</info-block>
</Info>
## Introductory USACO Problems
<problems-list problems={metadata.problems.usacoEasy} />
<Problems problems={metadata.problems.usacoEasy} />
## Knapsack
<problems-list problems={metadata.problems.knapsack} />
<Problems problems={metadata.problems.knapsack} />
## Paths in a Grid (and related)
<problems-list problems={metadata.problems.pathsGrid} />
<Problems problems={metadata.problems.pathsGrid} />
## Longest Increasing Subsequence
<problems-list problems={metadata.problems.lis} />
<Problems problems={metadata.problems.lis} />
## Harder USACO Problems
<problems-list problems={metadata.problems.usacoPast} />
<Problems problems={metadata.problems.usacoPast} />
## Other DP Problemsets
DP is a very important topic, so you should do a lot of practice on it.
<resources>
<resource source="AC" title="DP Contest" url="https://atcoder.jp/contests/dp/tasks" starred>very good!</resource>
<resource source="CSES" title="DP Section" url="https://cses.fi/problemset/list/" starred>also very good!</resource>
<resource source="CF" title="DP List" url="blog/entry/325">misc probs, a lot of which you don't need to know at this level</resource>
</resources>
<Resources>
<Resource source="AC" title="DP Contest" url="https://atcoder.jp/contests/dp/tasks" starred>very good!</Resource>
<Resource source="CSES" title="DP Section" url="https://cses.fi/problemset/list/" starred>also very good!</Resource>
<Resource source="CF" title="DP List" url="blog/entry/325">misc probs, a lot of which you don't need to know at this level</Resource>
</Resources>

View file

@ -30,22 +30,22 @@ export const metadata = {
}
}
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
## Tutorial
<resources>
<resource source="CF" title="DP on Trees" url="blog/entry/20935"> </resource>
<resource source="Philippines" title="DP on Trees and DAGs" url="https://noi.ph/training/weekly/week5.pdf">lol this code format is terrible </resource>
</resources>
<Resources>
<Resource source="CF" title="DP on Trees" url="blog/entry/20935"> </Resource>
<Resource source="Philippines" title="DP on Trees and DAGs" url="https://noi.ph/training/weekly/week5.pdf">lol this code format is terrible </Resource>
</Resources>
## Solving for All Roots
<problems-list problems={metadata.problems.allRoots} />
<Problems problems={metadata.problems.allRoots} />
(dfs twice)
<spoiler title="Solution">
<Spoiler title="Solution">
<LanguageSection>
@ -114,7 +114,7 @@ int main() {
</LanguageSection>
</spoiler>
</Spoiler>
## Combining Subtrees
@ -122,15 +122,15 @@ int main() {
## Problems
<info-block title="Pro Tip">
<Info title="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! Also, sometimes a greedy strategy suffices.
</info-block>
</Info>
<problems-list problems={metadata.problems.usaco} />
<Problems problems={metadata.problems.usaco} />
<spoiler title="Ostap & Tree">
<Spoiler title="Ostap & Tree">
```cpp
vmi yes[101], no[101];
@ -178,4 +178,4 @@ int main() {
}
```
</spoiler>
</Spoiler>

View file

@ -22,27 +22,27 @@ export const metadata = {
}
};
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
## Resources
<resources>
<resource source="CSA" title="Disjoint Data Sets" url="disjoint_data_sets" starred>both optimizations, diagrams</resource>
<resource source="CPH" title="15.2 - Union-Find">small to large, diagrams</resource>
<resource source="IUSACO" title="10.6 - Disjoint-Set Data Structure">path compression, diagrams</resource>
<resource source="PAPS" title="11.1 - Disjoint Sets">both optimizations, no diagrams</resource>
<resource source="TC" title="Disjoint Set Data Structures" url="disjoint-set-data-structures">diagrams</resource>
<resource source="CPC" title="3 - Data Structures" url="03_data_structures"></resource>
</resources>
<Resources>
<Resource source="CSA" title="Disjoint Data Sets" url="disjoint_data_sets" starred>both optimizations, diagrams</Resource>
<Resource source="CPH" title="15.2 - Union-Find">small to large, diagrams</Resource>
<Resource source="IUSACO" title="10.6 - Disjoint-Set Data Structure">path compression, diagrams</Resource>
<Resource source="PAPS" title="11.1 - Disjoint Sets">both optimizations, no diagrams</Resource>
<Resource source="TC" title="Disjoint Set Data Structures" url="disjoint-set-data-structures">diagrams</Resource>
<Resource source="CPC" title="3 - Data Structures" url="03_data_structures"></Resource>
</Resources>
Note: You may prefer to use this in place of DFS for computing connected components.
<optional-content title="DSU Complexity Proofs">
<Optional title="DSU Complexity Proofs">
- [$\log^* n$](https://en.wikipedia.org/wiki/Proof_of_O(log*n)\_time_complexity\_of_union%E2%80%93find)
- [$\alpha (m,n)$](https://dl.acm.org/doi/pdf/10.1145/321879.321884)
</optional-content>
</Optional>
## Implementations
@ -50,4 +50,4 @@ Note: You may prefer to use this in place of DFS for computing connected compone
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -18,11 +18,11 @@ export const metadata = {
}
};
<resources>
<resource source="CF" url="https://codeforces.com/blog/entry/60737" title="Chilli - Order of magnitude faster hash tables" starred>Introduces gp_hash_table</resource>
<resource source="GCC" url="https://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/gp_hash_table.html#Resize_Policy566860465" title="gp_hash_table Interface">documentation</resource>
<resource source="Benq (from KACTL)" title="HashMap" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/STL%20(5)/HashMap.h" starred> </resource>
</resources>
<Resources>
<Resource source="CF" url="https://codeforces.com/blog/entry/60737" title="Chilli - Order of magnitude faster hash tables" starred>Introduces gp_hash_table</Resource>
<Resource source="GCC" url="https://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/gp_hash_table.html#Resize_Policy566860465" title="gp_hash_table Interface">documentation</Resource>
<Resource source="Benq (from KACTL)" title="HashMap" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/STL%20(5)/HashMap.h" starred> </Resource>
</Resources>
<br />
@ -83,9 +83,9 @@ int main() {
When calling `g.resize(x)`, `x` is rounded up to the nearest power of 2. Then the actual size of `g` is changed to be equal to `x` (unless `x < g.size()`, in which case an error is thrown).
<resources>
<resource source="GCC" url="https://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/hash_standard_resize_policy.html" title="Resize Policy">documentation</resource>
</resources>
<Resources>
<Resource source="GCC" url="https://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/hash_standard_resize_policy.html" title="Resize Policy">documentation</Resource>
</Resources>
Furthermore, if we construct `g` with the following arguments:
@ -97,7 +97,7 @@ then the actual size of `g` is always at least `1<<16` (regardless of calls to `
### Solving ThreeSum
<problems-list problems={metadata.problems.three} />
<Problems problems={metadata.problems.three} />
You're supposed to use array since values are small :|

View file

@ -26,16 +26,16 @@ export const metadata = {
## Additional Resources
<resources>
<resource source="IUSACO" title="13 - Elementary Number Theory">module is based off this</resource>
<resource source="CPH" title="21.1, 21.2 - Number Theory">primes and factors, modular arithmetic</resource>
<resource source="PAPS" title="16 - Number Theory">same as below</resource>
<resource source="CF" title="CodeNCode - Number Theory Course" url="blog/entry/77137">lots of advanced stuff you don't need to know at this level</resource>
</resources>
<Resources>
<Resource source="IUSACO" title="13 - Elementary Number Theory">module is based off this</Resource>
<Resource source="CPH" title="21.1, 21.2 - Number Theory">primes and factors, modular arithmetic</Resource>
<Resource source="PAPS" title="16 - Number Theory">same as below</Resource>
<Resource source="CF" title="CodeNCode - Number Theory Course" url="blog/entry/77137">lots of advanced stuff you don't need to know at this level</Resource>
</Resources>
## Prime Factorization
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
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**.
@ -153,4 +153,4 @@ Also, one must always ensure that they do not attempt to divide by 0. Be aware t
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -29,18 +29,18 @@ export const metadata = {
## Sample
<problems-list problems={metadata.problems.standard} />
<Problems problems={metadata.problems.standard} />
## Resources
<resources>
<resource source="CPH" title="15 - Spanning Trees" starred>Kruskal's & Prim's</resource>
<resource source="PAPS" title="12.4">Kruskal's</resource>
<resource source="cp-algo" title="Prim's" url="graph/mst_prim.html"></resource>
<resource source="cp-algo" title="Kruskal's" url="graph/mst_kruskal.html"></resource>
<resource source="cp-algo" title="Kruskal's with DSU" url="graph/mst_kruskal_with_dsu.html"></resource>
</resources>
<Resources>
<Resource source="CPH" title="15 - Spanning Trees" starred>Kruskal's & Prim's</Resource>
<Resource source="PAPS" title="12.4">Kruskal's</Resource>
<Resource source="cp-algo" title="Prim's" url="graph/mst_prim.html"></Resource>
<Resource source="cp-algo" title="Kruskal's" url="graph/mst_kruskal.html"></Resource>
<Resource source="cp-algo" title="Kruskal's with DSU" url="graph/mst_kruskal_with_dsu.html"></Resource>
</Resources>
## USACO Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -23,7 +23,7 @@ export const metadata = {
}
};
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
<br/>
@ -31,26 +31,26 @@ A **segment tree** allows you to do point update and range query in $O(\log N)$
## Resources
<info-block title="Pro Tip">
<Info title="Pro Tip">
For gold, you only need to know the basics (ex. sum, min queries). You can skip more advanced applications such as **lazy propagation** for now.
</info-block>
</Info>
<resources>
<resource source="CSA" title="Segment Trees" url="segment_trees" starred>interactive</resource>
<resource source="CPH" title="9.3 - Segment Trees" starred>same implementation as below</resource>
<resource source="CPC" title="3 - Data Structures" url="03_data_structures" starred>see slides after union-find</resource>
<resource source="cp-algo" title="Segment Tree" url="data_structures/segment_tree.html" starred></resource>
<resource source="PAPS" title="11.2.3 - Segment Trees"></resource>
</resources>
<Resources>
<Resource source="CSA" title="Segment Trees" url="segment_trees" starred>interactive</Resource>
<Resource source="CPH" title="9.3 - Segment Trees" starred>same implementation as below</Resource>
<Resource source="CPC" title="3 - Data Structures" url="03_data_structures" starred>see slides after union-find</Resource>
<Resource source="cp-algo" title="Segment Tree" url="data_structures/segment_tree.html" starred></Resource>
<Resource source="PAPS" title="11.2.3 - Segment Trees"></Resource>
</Resources>
### Implementations
<resources>
<resource source="CF" title="AICash - Efficient and easy segment trees" url="blog/entry/18051" starred>simple implementation</resource>
<resource source="Benq" title="SegTree" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/1D%20Range%20Queries%20(9.2)/SegTree%20(9.2).h">based off above</resource>
</resources>
<Resources>
<Resource source="CF" title="AICash - Efficient and easy segment trees" url="blog/entry/18051" starred>simple implementation</Resource>
<Resource source="Benq" title="SegTree" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/1D%20Range%20Queries%20(9.2)/SegTree%20(9.2).h">based off above</Resource>
</Resources>
<LanguageSection>
@ -89,4 +89,4 @@ template<class T> struct Seg { // comb(ID,b) = b
Can also try solving some of tasks from both prerequisite articles.
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -44,7 +44,7 @@ export const metadata = {
## Binary Indexed Tree
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
A *Binary Indexed Tree* (aka *Fenwick Tree*) allows you to perform the following tasks in $O(\log N)$ time each on an array of size $N$:
@ -53,19 +53,19 @@ A *Binary Indexed Tree* (aka *Fenwick Tree*) allows you to perform the following
### Resources
<resources>
<resource source="CSA" title="Fenwick Trees" url="fenwick_trees" starred>interactive</resource>
<resource source="CPH" title="9.2, 9.4 - Binary Indexed Tree" starred>similar to above</resource>
<resource source="cp-algo" title="Fenwick Tree" url="data_structures/fenwick.html">also similar to above</resource>
<resource source="TC" title="Binary Indexed Trees" url="binary-indexed-trees"></resource>
</resources>
<Resources>
<Resource source="CSA" title="Fenwick Trees" url="fenwick_trees" starred>interactive</Resource>
<Resource source="CPH" title="9.2, 9.4 - Binary Indexed Tree" starred>similar to above</Resource>
<Resource source="cp-algo" title="Fenwick Tree" url="data_structures/fenwick.html">also similar to above</Resource>
<Resource source="TC" title="Binary Indexed Trees" url="binary-indexed-trees"></Resource>
</Resources>
### Implementations
<resources>
<resource source="CF" title="mouse_wireless - Multi-dimensional BITs with Templates" url="https://codeforces.com/blog/entry/64914" starred></resource>
<resource source="Benq" title="BIT" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/1D%20Range%20Queries%20(9.2)/BIT%20(9.2).h">based off above</resource>
</resources>
<Resources>
<Resource source="CF" title="mouse_wireless - Multi-dimensional BITs with Templates" url="https://codeforces.com/blog/entry/64914" starred></Resource>
<Resource source="Benq" title="BIT" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/1D%20Range%20Queries%20(9.2)/BIT%20(9.2).h">based off above</Resource>
</Resources>
(implementation)
@ -83,14 +83,14 @@ Suppose that we want a data structure that supports all the operations as a `set
Luckily, such a built-in data structure already exists in C++.
<resources>
<resource source="CF" url="blog/entry/11080" title="adamant - Policy Based Data Structures" starred> </resource>
<resource source="Benq" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/STL%20(5)/IndexedSet.h" title="Indexed Set"></resource>
</resources>
<Resources>
<Resource source="CF" url="blog/entry/11080" title="adamant - Policy Based Data Structures" starred> </Resource>
<Resource source="Benq" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/STL%20(5)/IndexedSet.h" title="Indexed Set"></Resource>
</Resources>
Using this, we can solve "Inversion Counting" in just a few lines (with template).
<!-- <spoiler title="INVCNT with Indexed Set"> -->
<!-- <Spoiler title="INVCNT with Indexed Set"> -->
```cpp
#include <bits/stdc++.h>
@ -117,7 +117,7 @@ int main() {
}
```
<!-- </spoiler> -->
<!-- </Spoiler> -->
Note that if it were not the case that all elements of the input array were distinct, then this code would be incorrect since `Tree<int>` would remove duplicates. Instead, we would use an indexed set of pairs (`Tree<pair<int,int>>`), where the first element of each pair would denote the value while the second would denote the position of the value in the array.
@ -125,17 +125,17 @@ Note that if it were not the case that all elements of the input array were dist
Assumes all updates are in the range $[1,N]$.
<resources>
<resource source="CF" url="blog/entry/11275" title="adamant - About Ordered Set" starred> log N </resource>
<resource source="GFG" url="order-statistic-tree-using-fenwick-tree-bit" title="Order Statistic Tree using BIT"> log^2 N </resource>
</resources>
<Resources>
<Resource source="CF" url="blog/entry/11275" title="adamant - About Ordered Set" starred> log N </Resource>
<Resource source="GFG" url="order-statistic-tree-using-fenwick-tree-bit" title="Order Statistic Tree using BIT"> log^2 N </Resource>
</Resources>
## Practice Problems
<problems-list problems={metadata.problems.practice} />
<Problems problems={metadata.problems.practice} />
## USACO Problems
Haircut, Balanced Photo, and Circle Cross are just variations on inversion counting.
<problems-list problems={metadata.problems.usaco} />
<Problems problems={metadata.problems.usaco} />

View file

@ -37,18 +37,18 @@ export const metadata = {
## Single-Source Shortest Path
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
### Tutorial
Use *Dijkstra's Algorithm*.
<resources>
<resource source="CPH" title="13.2 - Dijkstra" starred>code</resource>
<resource source="cp-algo" title="Dijkstra (Dense Graphs)" url="graph/dijkstra_dense.html"></resource>
<resource source="cp-algo" title="Dijkstra (Sparse Graphs)" url="graph/dijkstra_sparse.html"></resource>
<resource source="CPC" title="8 - Graphs 2" url="08_graphs_2"></resource>
</resources>
<Resources>
<Resource source="CPH" title="13.2 - Dijkstra" starred>code</Resource>
<Resource source="cp-algo" title="Dijkstra (Dense Graphs)" url="graph/dijkstra_dense.html"></Resource>
<Resource source="cp-algo" title="Dijkstra (Sparse Graphs)" url="graph/dijkstra_sparse.html"></Resource>
<Resource source="CPC" title="8 - Graphs 2" url="08_graphs_2"></Resource>
</Resources>
### Implementation
@ -61,39 +61,39 @@ The USACO training pages present a $O(N^2)$ version, although this is rarely use
#### Part 2: $O(M\log N)$
<resources>
<resource source="Benq" title="Dijkstra" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/graphs%20(12)/Basics/Dijkstra%20(7.3).h"> </resource>
</resources>
<Resources>
<Resource source="Benq" title="Dijkstra" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/graphs%20(12)/Basics/Dijkstra%20(7.3).h"> </Resource>
</Resources>
<IncompleteSection />
(comments in code?)
<optional-content title="Faster Dijkstra">
<Optional title="Faster Dijkstra">
Can be done in $O(M+N\log N)$ with [Fibonacci heap](https://en.wikipedia.org/wiki/Fibonacci_heap).
</optional-content>
</Optional>
### Problems
<problems-list problems={metadata.problems.dijk} />
<Problems problems={metadata.problems.dijk} />
## All Pairs Shortest Path (APSP)
<problems-list problems={metadata.problems.apspSam} />
<Problems problems={metadata.problems.apspSam} />
Use the *Floyd-Warshall* algorithm.
### Tutorial
<resources>
<resource source="CPH" title="13.3 - Floyd-Warshall" starred>example calculation, code</resource>
<resource source="PAPS" title="12.3.3"></resource>
<resource source="cp-algo" title="Floyd-Warshall" url="graph/all-pair-shortest-path-floyd-warshall.html"></resource>
</resources>
<Resources>
<Resource source="CPH" title="13.3 - Floyd-Warshall" starred>example calculation, code</Resource>
<Resource source="PAPS" title="12.3.3"></Resource>
<Resource source="cp-algo" title="Floyd-Warshall" url="graph/all-pair-shortest-path-floyd-warshall.html"></Resource>
</Resources>
<optional-content title="Incorrect Floyd-Warshall">
<Optional title="Incorrect Floyd-Warshall">
[Paper](https://arxiv.org/pdf/1904.01210.pdf)
@ -107,10 +107,10 @@ up to constant factors. Therefore, our results suggest that, if one is confused
the order of the triply nested loops, one can repeat the procedure three times
just to be safe.
</optional-content>
</Optional>
### Problems
<problems-list problems={metadata.problems.apsp} />
<Problems problems={metadata.problems.apsp} />
(more?)

View file

@ -31,22 +31,22 @@ With $O(N\log N)$ time preprocessing, we can get $O(1)$ queries.
First we'll consider the special case when $\ominus$ denotes `min`.
<problems-list problems={metadata.problems.rmqSample} />
<Problems problems={metadata.problems.rmqSample} />
### Resources
<resources>
<resource source="CPH" title="9.1 - Minimum Queries" starred>diagrams</resource>
<resource source="PAPS" title="11.2.2 - Sparse Tables" starred>code</resource>
<resource source="cp-algo" title="RMQ" url="sequences/rmq.html"></resource>
<resource source="cp-algo" title="Sparse Table" url="data_structures/sparse-table.html"></resource>
</resources>
<Resources>
<Resource source="CPH" title="9.1 - Minimum Queries" starred>diagrams</Resource>
<Resource source="PAPS" title="11.2.2 - Sparse Tables" starred>code</Resource>
<Resource source="cp-algo" title="RMQ" url="sequences/rmq.html"></Resource>
<Resource source="cp-algo" title="Sparse Table" url="data_structures/sparse-table.html"></Resource>
</Resources>
<optional-content title="Faster Preprocessing">
<Optional title="Faster Preprocessing">
[CF: $O(1)$ Query RMQ with $O(N)$ build](https://codeforces.com/blog/entry/78931)
</optional-content>
</Optional>
### Implementation
@ -54,7 +54,7 @@ First we'll consider the special case when $\ominus$ denotes `min`.
## Divide & Conquer
<problems-list problems={metadata.problems.diviSample} />
<Problems problems={metadata.problems.diviSample} />
**Divide & conquer** can refer to many different techniques. In this case, we use it to answer $Q$ queries offline in $O((N+Q)\log N)$ time.
@ -70,14 +70,14 @@ for each $M< r\le R$. Then the answer for all queries satisfying $l\le M< r$ is
Actually, this can be adjusted to answer queries online in $O(1)$ time each. See my implementation [here](https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/Static%20Range%20Queries%20(9.1)/RangeQuery.h).
<optional-content title="Faster Preprocessing">
<Optional title="Faster Preprocessing">
A data structure known as **sqrt-tree** can speed up preprocessing time to $O(N\log \log N)$.
- [CF Blog Pt 1](http://codeforces.com/blog/entry/57046)
- [CF Blog Pt 2](http://codeforces.com/blog/entry/59092)
</optional-content>
</Optional>
### Implementation
@ -85,4 +85,4 @@ A data structure known as **sqrt-tree** can speed up preprocessing time to $O(N\
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -24,7 +24,7 @@ export const metadata = {
}
};
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
<br/>
@ -79,4 +79,4 @@ ll query(int x) { auto it = m.lb(x);
<IncompleteSection />
<problems-list problems={metadata.problems.problems} />
<Problems problems={metadata.problems.problems} />

View file

@ -27,12 +27,12 @@ export const metadata = {
## Tutorial
<resources>
<resource source="CPH" title="26.3 - String Hashing" starred>good intro</resource>
<resource source="cp-algo" title="String Hashing" url="string/string-hashing.html" starred>code</resource>
<resource source="PAPS" title="14.3 - Hashing" starred>many applications</resource>
<Resources>
<Resource source="CPH" title="26.3 - String Hashing" starred>good intro</Resource>
<Resource source="cp-algo" title="String Hashing" url="string/string-hashing.html" starred>code</Resource>
<Resource source="PAPS" title="14.3 - Hashing" starred>many applications</Resource>
</resources>
</Resources>
### Implementation
@ -42,7 +42,7 @@ My implementation can be found [here](https://github.com/bqi343/USACO/blob/maste
## Example: Cownomics (Gold)
<problems-list problems={metadata.problems.ex} />
<Problems problems={metadata.problems.ex} />
- Use two pointers; for a fixed $l$, keep extending $r$ to the right until the positions $l\ldots r$ explain spotiness.
- Hashing gives you a way to quickly check whether two substrings of different cow types are equal. So for a single $[l,r]$ pair you can check whether it works in $O(N\log N)$ time (and you only need to check $O(M)$ of these pairs in total).
@ -52,15 +52,15 @@ My implementation can be found [here](https://github.com/bqi343/USACO/blob/maste
(elaborate)
<problems-list problems={metadata.problems.adj} />
<Problems problems={metadata.problems.adj} />
-->
## Hacking
<resources>
<resource source="CF" title="dacin21 - Anti-Hash Tests" url="blog/entry/60442">On CF educational rounds in particular, make sure to randomize your bases.</resource>
</resources>
<Resources>
<Resource source="CF" title="dacin21 - Anti-Hash Tests" url="blog/entry/60442">On CF educational rounds in particular, make sure to randomize your bases.</Resource>
</Resources>
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -33,22 +33,22 @@ To review, a **directed** graph consists of edges that can only be traversed in
## Topological Sort
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
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
<resources>
<resource source="CSA" title="Topological Sorting" url="topological_sorting" starred>both BFS, DFS</resource>
</resources>
<Resources>
<Resource source="CSA" title="Topological Sorting" url="topological_sorting" starred>both BFS, DFS</Resource>
</Resources>
### DFS
<resources>
<resource source="CPH" title="16.1, 16.2 - Topological Sorting">DFS</resource>
<resource source="cp-algo" title="Topological Sort" url="graph/topological-sort.html">DFS</resource>
</resources>
<Resources>
<Resource source="CPH" title="16.1, 16.2 - Topological Sorting">DFS</Resource>
<Resource source="cp-algo" title="Topological Sort" url="graph/topological-sort.html">DFS</Resource>
</Resources>
(implementation)
@ -64,17 +64,17 @@ The BFS version, known as [Kahn's Algorithm](https://en.wikipedia.org/wiki/Topol
## Dynamic Programming
<resources>
<resource source="PAPS" title="9.1">Best Path in a DAG</resource>
</resources>
<Resources>
<Resource source="PAPS" title="9.1">Best Path in a DAG</Resource>
</Resources>
One useful property of directed acyclic graphs is, as the name suggests, that no cycles exist. 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!
<problems-list problems={metadata.problems.dp} />
<Problems problems={metadata.problems.dp} />
In this task, we must find the longest path in a DAG.
<spoiler title="Solution">
<Spoiler title="Solution">
Let $dp[v]$ denote the length of the longest path ending at the node $v$. Clearly
@ -88,7 +88,7 @@ or zero if $v$ has in-degree $0$. If we process the states in topological order,
<IncompleteSection />
</spoiler>
</Spoiler>
<!-- However, not all problems clearly give you directed acyclic graphs (ex. [Plat - Cave Paintings](http://usaco.org/index.php?page=viewproblem2&cpid=996)). An important step in many problems is to reduce the statement into a directed acyclic graph. See the editorial of the linked problem for more information.
@ -96,4 +96,4 @@ or zero if $v$ has in-degree $0$. If we process the states in topological order,
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -34,15 +34,15 @@ export const metadata = {
## Introduction
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
If we can preprocess a rooted tree such that every subtree corresponds to a contiguous range on an array, we can do updates and range queries on it!
### Tutorial
<resources>
<resource source="CPH" title="18.2 - Subtrees & Paths" starred>introduces tree traversal array</resource>
</resources>
<Resources>
<Resource source="CPH" title="18.2 - Subtrees & Paths" starred>introduces tree traversal array</Resource>
</Resources>
### Implementation
@ -50,14 +50,14 @@ If we can preprocess a rooted tree such that every subtree corresponds to a cont
## LCA
<problems-list problems={metadata.problems.lca} />
<Problems problems={metadata.problems.lca} />
### Tutorial
<resources>
<resource source="CPH" title="18.3 - Least Common Ancestor (Method 2)" starred></resource>
<resource source="cp-algo" title="Reducing LCA to RMQ" url="graph/lca.html" starred></resource>
</resources>
<Resources>
<Resource source="CPH" title="18.3 - Least Common Ancestor (Method 2)" starred></Resource>
<Resource source="cp-algo" title="Reducing LCA to RMQ" url="graph/lca.html" starred></Resource>
</Resources>
### Implementation
@ -65,4 +65,4 @@ If we can preprocess a rooted tree such that every subtree corresponds to a cont
## Problems
<problems-list problems={metadata.problems.problems} />
<Problems problems={metadata.problems.problems} />

View file

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -36,38 +36,38 @@ See [my implementations](https://github.com/bqi343/USACO/tree/master/Implementat
## 2D RMQ
<resources>
<resource source="CF" title="retrograd - Multi-Dimensional RMQ" url="blog/entry/53810" starred></resource>
</resources>
<Resources>
<Resource source="CF" title="retrograd - Multi-Dimensional RMQ" url="blog/entry/53810" starred></Resource>
</Resources>
- GP of Serbia 2020 B
## 2D BIT
<problems-list problems={metadata.problems.bitSam} />
<Problems problems={metadata.problems.bitSam} />
### Tutorial
<resources>
<resource source="GFG" title="2D BIT" url="two-dimensional-binary-indexed-tree-or-fenwick-tree"></resource>
<resource source="TC" title="Binary Indexed Trees" url="binary-indexed-trees"></resource>
</resources>
<Resources>
<Resource source="GFG" title="2D BIT" url="two-dimensional-binary-indexed-tree-or-fenwick-tree"></Resource>
<Resource source="TC" title="Binary Indexed Trees" url="binary-indexed-trees"></Resource>
</Resources>
### Problems
<problems-list problems={metadata.problems.bit} />
<Problems problems={metadata.problems.bit} />
<optional-content title="Range Update and Range Query in Higher Dimensions">
<Optional title="Range Update and Range Query in Higher Dimensions">
Lazy propagation on segment trees does not extend to higher dimensions. However, you can extend the 1D BIT solution to solve range increment range sum in higher dimensions as well! See [this paper](https://arxiv.org/pdf/1311.6093.pdf) for details.
- USACO Camp - "Cows Play Global Thermonuclear War" (2D case)
</optional-content>
</Optional>
## 2D Offline Sum Queries
<problems-list problems={metadata.problems.offSam} />
<Problems problems={metadata.problems.offSam} />
The intended complexity is $O(N\log^2 N)$ with a good constant factor. This requires updating points and querying rectangle sums $N$ times for points with coordinates in the range $[1,N]$. However The 2D BITs mentioned above use $O(N^2)$ memory, which is too much. Since we know all of the updates and queries beforehand, we can reduce the memory usage while maintaining a decent constant factor.
@ -93,24 +93,24 @@ It's a bit difficult to pass the above problem within the time limit. Make sure
### Problems
<problems-list problems={metadata.problems.off} />
<Problems problems={metadata.problems.off} />
## 2D Segment Tree
Basically a segment tree of (maybe sparse) segment trees (or BBSTs, see "Advanced - Treap").
<info-block title="Pro Tip">
<Info title="Pro Tip">
This is **not** the same as [Quadtree](https://en.wikipedia.org/wiki/Quadtree). If the coordinates go up to $C$, then 2D segment tree queries run in $O(\log^2C)$ time each but some queries make Quadtree take $\Theta(C)$ time!
</info-block>
</Info>
### Short Description
<resources>
<resource source="CPH" title="28.2 (Sparse SegTree), 28.4 (2D)">brief description</resource>
<resource source="USACO" title="Analysis - Mowing the Field" url="http://www.usaco.org/current/data/sol_mowing_platinum_jan16.html">code</resource>
</resources>
<Resources>
<Resource source="CPH" title="28.2 (Sparse SegTree), 28.4 (2D)">brief description</Resource>
<Resource source="USACO" title="Analysis - Mowing the Field" url="http://www.usaco.org/current/data/sol_mowing_platinum_jan16.html">code</Resource>
</Resources>
### Reducing Memory Usage
@ -124,4 +124,4 @@ To resolve this, reduce the memory usage of sparse segment tree while maintaing
Can also try the USACO problems from above.
<problems-list problems={metadata.problems.seg} />
<Problems problems={metadata.problems.seg} />

View file

@ -34,25 +34,25 @@ export const metadata = {
}
};
<resources>
<resource source="CF" title="DFS Tree + Bridges" url="blog/entry/68138"> </resource>
</resources>
<Resources>
<Resource source="CF" title="DFS Tree + Bridges" url="blog/entry/68138"> </Resource>
</Resources>
## 2-Edge-Connected Components
<problems-list problems={metadata.problems.sam2} />
<Problems problems={metadata.problems.sam2} />
(implementation)
### With DSU
<problems-list problems={metadata.problems.disrupt} />
<Problems problems={metadata.problems.disrupt} />
The analysis for the above problem mentions an $O(m\alpha(n))$ solution. Although this is not a two-connected component problem, we can in fact use DSU to generate two-connected components.
(explanation?)
<spoiler title="Code">
<Spoiler title="Code">
The DSU operations take $O(\log n)$ rather than $O(\alpha(n))$ because the DSU does not use union by size, but it's easy to change this.
@ -95,17 +95,17 @@ struct TwoEdgeCC {
};
```
</spoiler>
</Spoiler>
### Problems
<problems-list problems={metadata.problems.probs2} />
<Problems problems={metadata.problems.probs2} />
- SRM 787 1000
## [Biconnected Components](https://en.wikipedia.org/wiki/Biconnected_component)
<problems-list problems={metadata.problems.bccSam} />
<Problems problems={metadata.problems.bccSam} />
note that BCCs contain EDGES not VERTICES
@ -117,12 +117,12 @@ Related topics include
### Tutorial
<resources>
<resource source="GFG" title="Articulation Points (aka Cut Vertices)" url="articulation-points-or-cut-vertices-in-a-graph">maybe not completely correct</resource>
</resources>
<Resources>
<Resource source="GFG" title="Articulation Points (aka Cut Vertices)" url="articulation-points-or-cut-vertices-in-a-graph">maybe not completely correct</Resource>
</Resources>
(implementation)
### Problems
<problems-list problems={metadata.problems.gen} />
<Problems problems={metadata.problems.gen} />

View file

@ -36,27 +36,27 @@ export const metadata = {
## Binary Jumping
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
## Lowest Common Ancestor
<problems-list problems={metadata.problems.lca} />
<Problems problems={metadata.problems.lca} />
### Tutorial
<resources>
<resource source="CPH" title="18.1, 18.3 (Method 1) - Finding Ancestors" starred></resource>
<resource source="cp-algo" title="LCA with Binary Lifting" url="graph/lca_binary_lifting.html"> </resource>
</resources>
<Resources>
<Resource source="CPH" title="18.1, 18.3 (Method 1) - Finding Ancestors" starred></Resource>
<Resource source="cp-algo" title="LCA with Binary Lifting" url="graph/lca_binary_lifting.html"> </Resource>
</Resources>
<optional-content title="Improvements">
<Optional title="Improvements">
- [CF: $O(\log N)$ queries and $O(N)$ memory](https://codeforces.com/blog/entry/74847)
- [Wikipedia: $O(1)$ queries and $O(N)$ preprocessing time](https://en.wikipedia.org/wiki/Level_ancestor_problem#Ladder_algorithm)
- though explanation is not the greatest
</optional-content>
</Optional>
### Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -35,17 +35,17 @@ export const metadata = {
tl;dr some operations are 32x-64x faster compared to a boolean array. See the [C++ Reference](http://www.cplusplus.com/reference/bitset/bitset/) for the operations you can perform.
<resources>
<resource source="CF" title="Errichto - Bitwise Operations Pt 2" url="blog/entry/73558"></resource>
</resources>
<Resources>
<Resource source="CF" title="Errichto - Bitwise Operations Pt 2" url="blog/entry/73558"></Resource>
</Resources>
## Knapsack
<problems-list problems={metadata.problems.school} />
<Problems problems={metadata.problems.school} />
Of course, the first step is to generate the sizes of each connected component.
<spoiler title="Input">
<Spoiler title="Input">
```cpp
#include <bits/stdc++.h>
@ -78,13 +78,13 @@ void init() {
}
```
</spoiler>
</Spoiler>
A naive knapsack solution would be as follows. For each $0\le i\le \texttt{comps.size()}$, let $\texttt{dp}[i][j]=1$ if there exists a subset of the first $i$ components whose sizes sum to $j$. Then the answer will be stored in $\texttt{dp}[i]$. This runs in $O(N^2)$ and is too slow if implemented naively, but we can use bitset to speed it up!
Note: you can't store all $N$ bitsets in memory at the same time (more on that below).
<spoiler title="Full Solution">
<Spoiler title="Full Solution">
```cpp
int main() {
@ -96,13 +96,13 @@ int main() {
}
```
</spoiler>
</Spoiler>
**Challenge**: This solution runs in $\approx 0.3\text{s}$ when $N=10^5$ and there are no edges. Find a faster solution which can also be sped up with bitset (my solution runs in 0.03s).
## Cowpatibility (Gold)
<problems-list problems={metadata.problems.cow} />
<Problems problems={metadata.problems.cow} />
Label the cows from $0\ldots N-1$. For two cows $x$ and $y$ set `adj[x][y]=1` if they share a common flavor. Then the number of pairs of cows that are compatible (counting each pair where $x$ and $y$ are distinct twice) is equal to the sum of `adj[x].count()` over all $x$. It remains to compute `adj[x]` for all $x$.
@ -110,7 +110,7 @@ Unfortunately, storing $N$ bitsets each with $N$ bits takes up $\frac{50000^2}{3
First, we read in all of the flavors.
<spoiler title="Input">
<Spoiler title="Input">
```cpp
#include <bits/stdc++.h>
@ -138,7 +138,7 @@ void input() {
}
```
</spoiler>
</Spoiler>
Then for each flavor, we can look at all pairs of cows that share that flavor and update the adjacency lists for those $x\in [0,HALF)$.
@ -162,7 +162,7 @@ for (int i = 1; i <= 1000000; ++i) if (flav[i].size() > 0) {
The full main function is as follows:
<spoiler title="Full Solution">
<Spoiler title="Full Solution">
```cpp
int main() {
@ -182,17 +182,17 @@ int main() {
}
```
</spoiler>
</Spoiler>
Apparently no test case contains more than $25000$ distinct colors, so we don't actually need to split the calculation into two halves.
## Lots of Triangles
<problems-list problems={metadata.problems.lots} />
<Problems problems={metadata.problems.lots} />
First, we read in the input data. `cross(a,b,c)` is positive iff `c` lies to the left of the line from `a` to `b`.
<spoiler title="Input">
<Spoiler title="Input">
```cpp
#include <bits/stdc++.h>
@ -222,11 +222,11 @@ void input() {
}
```
</spoiler>
</Spoiler>
There are $O(N^3)$ possible lots. Trying all possible lots and counting the number of trees that lie within each in $O(N)$ for a total time complexity of $O(N^4)$ should solve somewhere between 2 and 5 test cases. Given a triangle `t[0], t[1], t[2]` with positive area, tree `x` lies within it iff `x` is to the left of each of sides `(t[0],t[1])`,` (t[1],t[2])`, and `(t[2],t[0])`.
<spoiler title="Slow Solution">
<Spoiler title="Slow Solution">
```cpp
int main() {
@ -250,11 +250,11 @@ int main() {
}
```
</spoiler>
</Spoiler>
The analysis describes how to count the number of trees within a lot in $O(1)$, which is sufficient to solve the problem. However, $O(N)$ is actually sufficient as long as we divide by the bitset constant. Let `b[i][j][k]=1` if `k` lies to the left of side `(i,j)`. Then `x` lies within triangle `(t[0],t[1],t[2])` as long as `b[t[0]][t[1]][x]=b[t[1]][t[2]][x]=b[t[2]][t[0]][x]=1`. We can count the number of `x` such that this holds true by taking the bitwise AND of the bitsets for all three sides and then counting the number of bits in the result.
<spoiler title="Fast Solution">
<Spoiler title="Fast Solution">
```cpp
bitset<300> b[300][300];
@ -277,7 +277,7 @@ int main() {
for (int i = 0; i < N-2; ++i) cout << res[i] << "\n";
}
```
</spoiler>
</Spoiler>
## Knapsack Again (GP of Bytedance 2020 F)
@ -295,7 +295,7 @@ Since we only need to keep track of $2X+1$ values for each $i$, this solution ru
Intuitively, the random shuffle reduces the optimal subset to some random walk which should have variance at most $\max a_i\cdot \sqrt N$, so it suffices to take $X\approx \max a_i\cdot \sqrt N$. (Though I'm not completely convinced that this works, does anyone know how to bound the failure probability of this algorithm precisely?)
<spoiler title="Solution">
<Spoiler title="Solution">
```cpp
#include <bits/stdc++.h>
@ -335,7 +335,7 @@ int main() {
for (int i = 0; i < T; ++i) cout << solve() << "\n";
}
```
</spoiler>
</Spoiler>
## Other Applications
@ -349,10 +349,10 @@ Operations such as `_Find_first()` and `_Find_next()` mentioned in Errichto's bl
Regarding the last application:
<problems-list problems={metadata.problems.bfs} />
<Problems problems={metadata.problems.bfs} />
In USACO Camp, this problem appeared with $N\le 10^5$ and a large time limit ...
## Additional Problems
<problems-list problems={metadata.problems.ad} />
<Problems problems={metadata.problems.ad} />

View file

@ -25,13 +25,13 @@ export const metadata = {
### Tutorial
<resources>
<resource source="Carpanese" title="Illustrated Intro to Centroid Decomposition" url="https://medium.com/carpanese/an-illustrated-introduction-to-centroid-decomposition-8c1989d53308" starred></resource>
<resource source="GFG" title="Centroid Decomposition of Tree" url="centroid-decomposition-of-tree"></resource>
</resources>
<Resources>
<Resource source="Carpanese" title="Illustrated Intro to Centroid Decomposition" url="https://medium.com/carpanese/an-illustrated-introduction-to-centroid-decomposition-8c1989d53308" starred></Resource>
<Resource source="GFG" title="Centroid Decomposition of Tree" url="centroid-decomposition-of-tree"></Resource>
</Resources>
### Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
*Note:* Unfortunately, it seems like constant factor is especially important for DMOJ. :|

View file

@ -31,31 +31,31 @@ export const metadata = {
}
};
<info-block title="Pro Tip">
<Info title="Pro Tip">
You can often use this to solve subtasks.
</info-block>
</Info>
## Tutorial
<resources>
<resource source="PAPS" title="9.4"> </resource>
<resource source="CPH" title="10 (Bit Manipulation), 19.2 (Hamiltonian Paths)"> </resource>
<resource source="CF" title="DP Over Subsets" url="blog/entry/337"> </resource>
<resource source="HE" title="DP and Bit Masking" url="https://www.hackerearth.com/practice/algorithms/dynamic-programming/bit-masking/tutorial/"> </resource>
</resources>
<Resources>
<Resource source="PAPS" title="9.4"> </Resource>
<Resource source="CPH" title="10 (Bit Manipulation), 19.2 (Hamiltonian Paths)"> </Resource>
<Resource source="CF" title="DP Over Subsets" url="blog/entry/337"> </Resource>
<Resource source="HE" title="DP and Bit Masking" url="https://www.hackerearth.com/practice/algorithms/dynamic-programming/bit-masking/tutorial/"> </Resource>
</Resources>
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
## DP on Broken Profile
<resources>
<resource source="cp-algo" title="DP on Broken Profile" url="dynamic_programming/profile-dynamics.html"> </resource>
</resources>
<Resources>
<Resource source="cp-algo" title="DP on Broken Profile" url="dynamic_programming/profile-dynamics.html"> </Resource>
</Resources>
(fill in? more probs?)
<problems-list problems={metadata.problems.broken} />
<Problems problems={metadata.problems.broken} />

View file

@ -12,14 +12,14 @@ Mowing: http://www.usaco.org/index.php?page=viewproblem2&cpid=926
Miscellaneous Techniques: https://codeforces.com/blog/entry/47764
<info-block title="Pro Tip">
<Info title="Pro Tip">
There are [plenty](https://github.com/bqi343/USACO/blob/master/Contests/USACO%20Links/Division-Specific/Platinum.md) of Platinum DP problems that are not covered by this guide; we recommend that you work through these on your own.
</info-block>
</Info>
<optional-content title="Application">
<Optional title="Application">
Queue w/ Two Stacks is used to remove a factor of $O(\log N)$ in [USACO Plat - Mowing Mischief](http://www.usaco.org/index.php?page=viewproblem2&cpid=926).
</optional-content>
</Optional>

View file

@ -28,6 +28,6 @@ export const metadata = {
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
* TC SRM 787 500

View file

@ -31,7 +31,7 @@ no path compression
(tutorial?)
<problems-list problems={metadata.problems.rollback} />
<Problems problems={metadata.problems.rollback} />
## Dynamic Insertion
@ -39,4 +39,4 @@ mention sqrt
(online Aho-Corasick)
<problems-list problems={metadata.problems.ins} />
<Problems problems={metadata.problems.ins} />

View file

@ -28,7 +28,7 @@ export const metadata = {
### Standard
<problems-list problems={metadata.problems.sam} />
<Problems problems={metadata.problems.sam} />
### Tutorial
@ -36,4 +36,4 @@ export const metadata = {
### Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -26,12 +26,12 @@ export const metadata = {
## Example 1
<problems-list problems={metadata.problems.e1} />
<Problems problems={metadata.problems.e1} />
## Example 2
<problems-list problems={metadata.problems.e2} />
<Problems problems={metadata.problems.e2} />
Extension:
<problems-list problems={metadata.problems.other} />
<Problems problems={metadata.problems.other} />

View file

@ -40,30 +40,30 @@ export const metadata = {
## Maximum Flow
<problems-list problems={metadata.problems.maxSam} />
<Problems problems={metadata.problems.maxSam} />
### Tutorial
<resources>
<resource source="CPC" title="10 - Network Flow" url="10_graphs_3_network_flow"> </resource>
<resource source="CPH" title="20 - Flows & Cuts"> </resource>
</resources>
<Resources>
<Resource source="CPC" title="10 - Network Flow" url="10_graphs_3_network_flow"> </Resource>
<Resource source="CPH" title="20 - Flows & Cuts"> </Resource>
</Resources>
### Problems
<problems-list problems={metadata.problems.flow} />
<Problems problems={metadata.problems.flow} />
## Bipartite Matching
<problems-list problems={metadata.problems.match} />
<Problems problems={metadata.problems.match} />
## Dinic's Algorithm
<problems-list problems={metadata.problems.dinic} />
<Problems problems={metadata.problems.dinic} />
Hopcroft-Karp Bipartite Matching?
<optional-content title="Faster Flow">
<Optional title="Faster Flow">
There exist faster flow algorithms such as **Push-Relabel**. Also see the following blog post:
@ -71,11 +71,11 @@ There exist faster flow algorithms such as **Push-Relabel**. Also see the follow
However, the standard implementation of Dinic's is (almost) always fast enough.
</optional-content>
</Optional>
## Min-Cut Max Flow
<problems-list problems={metadata.problems.minEx} />
<Problems problems={metadata.problems.minEx} />
(show equivalence)
@ -89,4 +89,4 @@ https://maps20.kattis.com/problems/thewrathofkahn
## Problems
<problems-list problems={metadata.problems.cut} />
<Problems problems={metadata.problems.cut} />

View file

@ -39,11 +39,11 @@ Suppose that you have a rooted tree where each vertex $i$ has a value $v_i$. Als
We'll focus on the first approach.
<optional-content title="A Faster Solution">
<Optional title="A Faster Solution">
There are ways to do this in $O(K)$ time for a binary tree if you don't need to return the values in sorted order (see [here](https://www.sciencedirect.com/science/article/pii/S0890540183710308)).
</optional-content>
</Optional>
### Generalizing
@ -85,7 +85,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.
<spoiler title="My Solution">
<Spoiler title="My Solution">
```cpp
#include <bits/stdc++.h>
@ -142,12 +142,12 @@ int main() {
}
```
</spoiler>
</Spoiler>
## Robotic Cow Herd
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
As with the analysis, for each location you should
@ -161,7 +161,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.
<spoiler title="My Solution 1">
<Spoiler title="My Solution 1">
```cpp
#include <bits/stdc++.h>
@ -220,7 +220,7 @@ int main() {
}
```
</spoiler>
</Spoiler>
### Approach 2
@ -256,7 +256,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.
<spoiler title="My Solution 2">
<Spoiler title="My Solution 2">
```cpp
#include <bits/stdc++.h>
@ -304,8 +304,8 @@ int main() {
}
```
</spoiler>
</Spoiler>
## Other Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -32,29 +32,29 @@ You should know basic operations like cross product and dot product.
### Tutorial
<resources>
<resource source="CF" title="C++ - std::complex" url="blog/entry/22175" starred>short description of operations</resource>
<resource source="CPH" title="29 - Geometry" starred>Complex #s, Points & Lines, Polygons, Distances</resource>
<resource source="CF" title="Point Struct" url="blog/entry/48122" starred>code, examples</resource>
<resource source="cp-algo" title="Geometry - Elementary Operations" url="https://cp-algorithms.com/" starred></resource>
<resource source="CPC" title="12 - geometry" url="12_geometry" starred>basics, polygon area, point in polygon</resource>
<resource source="CF" title="vlecomte - Geometry Handbook" url="blog/entry/59129" starred>some material is quite advanced</resource>
<resource source="TC" title="Basic Geometry Concepts Pts 1,2" url="geometry-concepts-basic-concepts">broken code format</resource>
</resources>
<Resources>
<Resource source="CF" title="C++ - std::complex" url="blog/entry/22175" starred>short description of operations</Resource>
<Resource source="CPH" title="29 - Geometry" starred>Complex #s, Points & Lines, Polygons, Distances</Resource>
<Resource source="CF" title="Point Struct" url="blog/entry/48122" starred>code, examples</Resource>
<Resource source="cp-algo" title="Geometry - Elementary Operations" url="https://cp-algorithms.com/" starred></Resource>
<Resource source="CPC" title="12 - geometry" url="12_geometry" starred>basics, polygon area, point in polygon</Resource>
<Resource source="CF" title="vlecomte - Geometry Handbook" url="blog/entry/59129" starred>some material is quite advanced</Resource>
<Resource source="TC" title="Basic Geometry Concepts Pts 1,2" url="geometry-concepts-basic-concepts">broken code format</Resource>
</Resources>
- [My Templates](https://github.com/bqi343/USACO/tree/master/Implementations/content/geometry%20(13)/Primitives)
### Standard Problems
<resources>
<resource source="IUSACO" title="14.2 - Segment Intersection"></resource>
</resources>
<Resources>
<Resource source="IUSACO" title="14.2 - Segment Intersection"></Resource>
</Resources>
<problems-list problems={metadata.problems.standard} />
<Problems problems={metadata.problems.standard} />
### Misc Problems
<problems-list problems={metadata.problems.other} />
<Problems problems={metadata.problems.other} />
- [Racing Off Track](https://open.kattis.com/contests/acpc17open/problems/racingofftrack) (link doesn't work ...)
- [TopCoder Watchtower](https://community.topcoder.com/stat?c=problem_statement&pm=2014&rd=4685)

View file

@ -30,23 +30,23 @@ export const metadata = {
}
};
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
## Tutorial
<resources>
<resource source="cp-algo" title="HLD" url="https://cp-algorithms.com/graph/hld.html" starred>For an alternate implementation, see below</resource>
<resource source="anudeep2011" title="HLD" url="https://blog.anudeep2011.com/heavy-light-decomposition/">explains what HLD is (but incomplete & overly complicated code)</resource>
</resources>
<Resources>
<Resource source="cp-algo" title="HLD" url="https://cp-algorithms.com/graph/hld.html" starred>For an alternate implementation, see below</Resource>
<Resource source="anudeep2011" title="HLD" url="https://blog.anudeep2011.com/heavy-light-decomposition/">explains what HLD is (but incomplete & overly complicated code)</Resource>
</Resources>
## Implementations
<resources>
<resource source="CF" title="AI-Cash - HLD Implementation" url="blog/entry/22072" starred />
<resource source="CF" title="adamant - Easiest HLD with subtree queries" url="blog/entry/53170" starred>not complete</resource>
<resource source="Benq" title="Complete HLD Implementation" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/graphs%20(12)/Trees%20(10)/HLD%20(10.3).h" starred>complete implementation following the above two articles with minor modifications</resource>
</resources>
<Resources>
<Resource source="CF" title="AI-Cash - HLD Implementation" url="blog/entry/22072" starred />
<Resource source="CF" title="adamant - Easiest HLD with subtree queries" url="blog/entry/53170" starred>not complete</Resource>
<Resource source="Benq" title="Complete HLD Implementation" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/graphs%20(12)/Trees%20(10)/HLD%20(10.3).h" starred>complete implementation following the above two articles with minor modifications</Resource>
</Resources>
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -37,7 +37,7 @@ export const metadata = {
## [Convex Hull](https://en.wikipedia.org/wiki/Convex_hull_algorithms)
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
### Tutorial
@ -49,25 +49,25 @@ export const metadata = {
- [Wikipedia](https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain)
- [My Implementation](https://github.com/bqi343/USACO/blob/master/Implementations/content/geometry%20(13)/Polygons/ConvexHull%20(13.2).h)
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
## Rotating Caliphers
<problems-list problems={metadata.problems.sample2} />
<Problems problems={metadata.problems.sample2} />
<resources>
<resource source="CF" title="Rotating calipers technique and applications" url="blog/entry/46162"> </resource>
</resources>
<Resources>
<Resource source="CF" title="Rotating calipers technique and applications" url="blog/entry/46162"> </Resource>
</Resources>
<problems-list problems={metadata.problems.rotating} />
<Problems problems={metadata.problems.rotating} />
## Convex Hull Trick
<resources>
<resource source="cp-algo" title="Convex Hull Trick" url="geometry/convex_hull_trick.html" starred> </resource>
<resource source="CF" title="Convex Hull Trick - Geo Being Useful" url="blog/entry/63823" starred> </resource>
</resources>
<Resources>
<Resource source="cp-algo" title="Convex Hull Trick" url="geometry/convex_hull_trick.html" starred> </Resource>
<Resource source="CF" title="Convex Hull Trick - Geo Being Useful" url="blog/entry/63823" starred> </Resource>
</Resources>
<problems-list problems={metadata.problems.cht} />
<Problems problems={metadata.problems.cht} />
https://codeforces.com/contest/1083/problem/E

View file

@ -29,25 +29,25 @@ export const metadata = {
## Half-Plane Intersection
<resources>
<resource source="CF" title="Blogewoosh - Half-Plane Intersection w/ Ternary Search" url="blog/entry/61710" starred></resource>
<resource source="Petr" title="Linear Half-Plane Intersection" url="https://petr-mitrichev.blogspot.com/2016/07/a-half-plane-week.html" starred>expected linear!</resource>
</resources>
<Resources>
<Resource source="CF" title="Blogewoosh - Half-Plane Intersection w/ Ternary Search" url="blog/entry/61710" starred></Resource>
<Resource source="Petr" title="Linear Half-Plane Intersection" url="https://petr-mitrichev.blogspot.com/2016/07/a-half-plane-week.html" starred>expected linear!</Resource>
</Resources>
<problems-list problems={metadata.problems.half} />
<Problems problems={metadata.problems.half} />
## LineContainer
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
<resources>
<resource source="KACTL" title="LineContainer" url="https://github.com/kth-competitive-programming/kactl/blob/master/content/data-structures/LineContainer.h" starred>code</resource>
<resource source="cp-algo" title="Lichao Tree" url="geometry/convex_hull_trick.html" starred> </resource>
<resource source="CF" title="retrograd - Half-Plane Set" url="blog/entry/61710?#comment-457662">code</resource>
</resources>
<Resources>
<Resource source="KACTL" title="LineContainer" url="https://github.com/kth-competitive-programming/kactl/blob/master/content/data-structures/LineContainer.h" starred>code</Resource>
<Resource source="cp-algo" title="Lichao Tree" url="geometry/convex_hull_trick.html" starred> </Resource>
<Resource source="CF" title="retrograd - Half-Plane Set" url="blog/entry/61710?#comment-457662">code</Resource>
</Resources>
## Problems
<problems-list problems={metadata.problems.probs} />
<Problems problems={metadata.problems.probs} />
https://atcoder.jp/contests/arc066/tasks/arc066_d

View file

@ -25,16 +25,16 @@ export const metadata = {
adding lambda\*smth
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
## Tutorial
<resources>
<resource source="Mamnoon Siam" title="Attack on Aliens" url="https://mamnoonsiam.github.io/posts/attack-on-aliens.html"></resource>
</resources>
<Resources>
<Resource source="Mamnoon Siam" title="Attack on Aliens" url="https://mamnoonsiam.github.io/posts/attack-on-aliens.html"></Resource>
</Resources>
## Problems
<problems-list problems={metadata.problems.probs} />
<Problems problems={metadata.problems.probs} />
(300iq insane problems???)

View file

@ -29,17 +29,17 @@ export const metadata = {
## Additional Reading
<resources>
<resource source="CPH" title="18.4 - Merging Data Structures"></resource>
<resource source="CF" title="Arpa - Sack (DSU on Tree)" url="blog/entry/44351"></resource>
<resource source="CF" title="tuwuna - Explaining DSU on Trees" url="blog/entry/67696"></resource>
</resources>
<Resources>
<Resource source="CPH" title="18.4 - Merging Data Structures"></Resource>
<Resource source="CF" title="Arpa - Sack (DSU on Tree)" url="blog/entry/44351"></Resource>
<Resource source="CF" title="tuwuna - Explaining DSU on Trees" url="blog/entry/67696"></Resource>
</Resources>
## Merging Data Structures
Obviously [linked lists](http://www.cplusplus.com/reference/list/list/splice/) can be merged in $O(1)$ time. But what about sets or vectors?
<problems-list problems={metadata.problems.sam} />
<Problems problems={metadata.problems.sam} />
Let's consider a tree rooted at node $1$, where each node has a color.
@ -70,7 +70,7 @@ Note that [swap](http://www.cplusplus.com/reference/utility/swap/) exchanges two
**Proof:** 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 at least $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.
<spoiler title="Full Code">
<Spoiler title="Full Code">
```cpp
#include <bits/stdc++.h>
@ -115,7 +115,7 @@ int main() {
}
```
</spoiler>
</Spoiler>
## Generalizing
@ -123,9 +123,9 @@ A set doesn't have to be an `std::set`. Many data structures can be merged, such
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
<spoiler title="Solution to Promotion Counting">
<Spoiler title="Solution to Promotion Counting">
```cpp
#include <bits/stdc++.h>
@ -172,12 +172,12 @@ int main() {
}
```
</spoiler>
</Spoiler>
(also: same solution w/o indexed set)
<optional-content title="Faster Merging">
<Optional title="Faster Merging">
It's easy to merge two sets of sizes $n\ge m$ in $O(n+m)$ or $(m\log n)$ time, but sometimes $O\left(m\log \left(1+\frac{n}{m}\right)\right)$ can be significantly better than both of these. Check "Advanced - Treaps" for more details. Also see [this link](https://codeforces.com/blog/entry/49446) regarding merging segment trees.
</optional-content>
</Optional>

View file

@ -39,39 +39,39 @@ export const metadata = {
## BIT Revisited
<problems-list problems={metadata.problems.bitSample} />
<Problems problems={metadata.problems.bitSample} />
Binary Indexed Trees can support range increments in addition to range sum queries.
### Tutorial
<resources>
<resource source="GFG" title="Range Update Point Query" url="binary-indexed-tree-range-updates-point-queries/"></resource>
<resource source="GFG" title="Range Update Range Query" url="binary-indexed-tree-range-update-range-queries/"></resource>
</resources>
<Resources>
<Resource source="GFG" title="Range Update Point Query" url="binary-indexed-tree-range-updates-point-queries/"></Resource>
<Resource source="GFG" title="Range Update Range Query" url="binary-indexed-tree-range-update-range-queries/"></Resource>
</Resources>
[My Implementation](https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/1D%20Range%20Queries%20(9.2)/BITrange.h)
### Problems
<problems-list problems={metadata.problems.bitProb} />
<Problems problems={metadata.problems.bitProb} />
## Lazy Segment Tree
<problems-list problems={metadata.problems.lazySample} />
<Problems problems={metadata.problems.lazySample} />
### Tutorial
<resources>
<resource source="CPH" title="28.1 - Segment Trees Revisited" starred>short description</resource>
<resource source="CSA" title="Segment Trees" url="segment_trees" starred>interactive</resource>
<resource source="cp-algo" title="Segment Tree" url="data_structures/segment_tree.html" starred>adding on segments, assigning</resource>
<resource source="CF" title="Efficient and easy segment trees" url="blog/entry/18051">code is more confusing than recursive version</resource>
</resources>
<Resources>
<Resource source="CPH" title="28.1 - Segment Trees Revisited" starred>short description</Resource>
<Resource source="CSA" title="Segment Trees" url="segment_trees" starred>interactive</Resource>
<Resource source="cp-algo" title="Segment Tree" url="data_structures/segment_tree.html" starred>adding on segments, assigning</Resource>
<Resource source="CF" title="Efficient and easy segment trees" url="blog/entry/18051">code is more confusing than recursive version</Resource>
</Resources>
### Problems
<problems-list problems={metadata.problems.lazySegTree} />
<Problems problems={metadata.problems.lazySegTree} />
## Lazy Segment Tree - Counting Minimums
@ -79,4 +79,4 @@ use segment tree that keeps track of minimum and # of minimums
(describe)
<problems-list problems={metadata.problems.lazySegCnt} />
<Problems problems={metadata.problems.lazySegCnt} />

View file

@ -32,7 +32,7 @@ export const metadata = {
## SCCs
<problems-list problems={metadata.problems.ex} />
<Problems problems={metadata.problems.ex} />
### Tutorial
@ -40,27 +40,27 @@ export const metadata = {
- [Tarjan](https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm)
- [Kosaraju](https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm)
<resources>
<resource source="CPH" title="17 - Strong Connectivity"></resource>
<resource source="CPC" title="7 - Graphs 1" url="07_graphs_1"></resource>
</resources>
<Resources>
<Resource source="CPH" title="17 - Strong Connectivity"></Resource>
<Resource source="CPC" title="7 - Graphs 1" url="07_graphs_1"></Resource>
</Resources>
(impls)
### Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
## 2-SAT
<problems-list problems={metadata.problems.satEx} />
<Problems problems={metadata.problems.satEx} />
(impl)
### Tutorial
<resources>
<resource source="CF" title="2-SAT" url="blog/entry/16205"></resource>
</resources>
<Resources>
<Resource source="CF" title="2-SAT" url="blog/entry/16205"></Resource>
</Resources>
(KACTL at most one?)

View file

@ -27,18 +27,18 @@ export const metadata = {
}
};
<problems-list problems={metadata.problems.sam} />
<Problems problems={metadata.problems.sam} />
<br/>
### Tutorial
<resources title="SSSP Negative">
<resource source="CPH" title="13.1"></resource>
<resource source="cp-algo" title="Bellman-Ford" url="graph/bellman_ford.html"></resource>
<resource source="cp-algo" title="Finding Negative Cycle" url="finding-negative-cycle-in-graph.html"></resource>
<resource source="TC" title="Intro to Graphs Section 3" url="introduction-to-graphs-and-their-data-structures-section-3/"></resource>
</resources>
<Resources title="SSSP Negative">
<Resource source="CPH" title="13.1"></Resource>
<Resource source="cp-algo" title="Bellman-Ford" url="graph/bellman_ford.html"></Resource>
<Resource source="cp-algo" title="Finding Negative Cycle" url="finding-negative-cycle-in-graph.html"></Resource>
<Resource source="TC" title="Intro to Graphs Section 3" url="introduction-to-graphs-and-their-data-structures-section-3/"></Resource>
</Resources>
Can also use [Shortest Path Faster Algorithm](https://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm) or modify Dijkstra slightly (though the same running time bound no longer applies).
@ -46,7 +46,7 @@ Can also use [Shortest Path Faster Algorithm](https://en.wikipedia.org/wiki/Shor
### Problems
<problems-list problems={metadata.problems.probs} />
<Problems problems={metadata.problems.probs} />
## Simple Linear Programming
@ -54,9 +54,9 @@ You can also use shortest path algorithms to solve the following problem (a very
> Given variables $x_1,x_2,\ldots,x_N$ with constraints in the form $x_i-x_j\ge c$, compute a feasible solution.
<resources>
<resource source="MIT" title="Slides from Intro to Algorithms" url="https://www.cs.rit.edu/~spr/COURSES/ALG/MIT/lec18.pdf">Linear Programming Trick</resource>
</resources>
<Resources>
<Resource source="MIT" title="Slides from Intro to Algorithms" url="https://www.cs.rit.edu/~spr/COURSES/ALG/MIT/lec18.pdf">Linear Programming Trick</Resource>
</Resources>
**Example:** Timeline (USACO Camp)
@ -64,4 +64,4 @@ You can also use shortest path algorithms to solve the following problem (a very
### Problems
<problems-list problems={metadata.problems.linear} />
<Problems problems={metadata.problems.linear} />

View file

@ -41,7 +41,7 @@ export const metadata = {
## Walking on a Segment Tree
<problems-list problems={metadata.problems.walkSam} />
<Problems problems={metadata.problems.walkSam} />
You want to support queries of the following form on an array $a_1,\ldots,a_N$ (along with point updates).
@ -49,26 +49,26 @@ You want to support queries of the following form on an array $a_1,\ldots,a_N$ (
Of course, you can do this in $O(\log^2N)$ time with a max segment tree and binary searching on the first $i$ such that $\max(a_1,\ldots,a_i)\ge x$. But try to do this in $O(\log N)$ time.
<problems-list problems={metadata.problems.walk} />
<Problems problems={metadata.problems.walk} />
## Combining
<problems-list problems={metadata.problems.combSam} />
<Problems problems={metadata.problems.combSam} />
(solution to above problem)
<problems-list problems={metadata.problems.comb} />
<Problems problems={metadata.problems.comb} />
## Wavelet Tree
<problems-list problems={metadata.problems.waveletSam} />
<Problems problems={metadata.problems.waveletSam} />
### Tutorial
<resources>
<resource source="CF" title="Intro to New DS: Wavelet Trees" url="blog/entry/52854"></resource>
</resources>
<Resources>
<Resource source="CF" title="Intro to New DS: Wavelet Trees" url="blog/entry/52854"></Resource>
</Resources>
### Problems
<problems-list problems={metadata.problems.wavelet} />
<Problems problems={metadata.problems.wavelet} />

View file

@ -39,10 +39,10 @@ export const metadata = {
## Tutorials
<resources>
<resource source="CF" title="zscoder - Slope Trick" url="blog/entry/47821">3 problems using this trick</resource>
<resource source="CF" title="Kuroni - Slope Trick Explained" url="blog/entry/77298">clarifying the above and another example problem</resource>
</resources>
<Resources>
<Resource source="CF" title="zscoder - Slope Trick" url="blog/entry/47821">3 problems using this trick</Resource>
<Resource source="CF" title="Kuroni - Slope Trick Explained" url="blog/entry/77298">clarifying the above and another example problem</Resource>
</Resources>
From the latter link (modified):
@ -53,27 +53,27 @@ From the latter link (modified):
It's generally applicable as a DP optimization.
<info-block title="Pro Tip">
<Info title="Pro Tip">
Usually you can come up with a slower (usually $O(N^2)$) DP first and then optimize it to $O(N\log N)$ with slope trick.
</info-block>
</Info>
The rest of this module assumes that you know the basic idea of this trick. In particular, you should be at least somewhat familiar with the $O(N\log N)$ time solution to the first problem in zscoder's tutorial:
<problems-list problems={metadata.problems.ex} />
<Problems problems={metadata.problems.ex} />
It's ok if you found the explanations confusing; the example below should help clarify.
## Buy Low Sell High
<problems-list problems={metadata.problems.buy} />
<Problems problems={metadata.problems.buy} />
### Slow Solution
Let $dp[i][j]$ denote the maximum amount of money you can have on day $i$ if you have exactly $j$ shares of stock on that day. The final answer will be $dp[N][0]$. This solution runs in $O(N^2)$ time.
<spoiler title="Slow Code">
<Spoiler title="Slow Code">
```cpp
@ -104,7 +104,7 @@ int main() {
}
```
</spoiler>
</Spoiler>
If we run this on the first sample case, then we get the following table:
@ -136,7 +136,7 @@ Then $dif[i][j]\le dif[i][j+1]$ for all $j\ge 0$. In other words, $dp[i][j]$ as
### Full Solution
<spoiler title="Explanation">
<Spoiler title="Explanation">
We'll process the shares in order. Suppose that we are currently considering the $i$-th day, where shares are worth $p_i$. We can replace (buy or sell a share) in the statement with (buy, then sell somewhere between 0 and 2 shares).
@ -178,9 +178,9 @@ dif[5] = { 7, 7, 9, 9, 10}
(insert diagrams)
</spoiler>
</Spoiler>
<spoiler title="My Code">
<Spoiler title="My Code">
The implementation is quite simple; maintain a priority queue representing $dif[i]$ that allows you to pop the minimum element. After adding $i$ elements, $ans$ stores the current value of $dp[i][i]$. At the end, you add all the differences in $dif[N]$ to go from $dp[N][N]$ to $dp[N][0]$.
@ -204,7 +204,7 @@ int main() {
}
```
</spoiler>
</Spoiler>
### Extension
@ -212,7 +212,7 @@ int main() {
## Potatoes & Fertilizers
<problems-list problems={metadata.problems.potatoes} />
<Problems problems={metadata.problems.potatoes} />
### Simplifying the Problem
@ -236,7 +236,7 @@ For each $0\le i\le N$ and $0\le j\le d_N$, let $dp[i][j]$ be the minimum cost t
### Full Solution
<spoiler title="Explanation">
<Spoiler title="Explanation">
Similar to before, this DP is concave up for a fixed $i$! Given a piecewise linear function $f_i(x)$ that takes as input $x$ and outputs $dp[i][x]$, we need to support the following two operations to transform this function into $f_{i+1}$.
@ -250,9 +250,9 @@ Again, these can be done with a priority queue. Instead of storing the consecuti
This solution runs in $O(N\log N)$ time.
</spoiler>
</Spoiler>
<spoiler title="My Code">
<Spoiler title="My Code">
```cpp
#include <bits/stdc++.h>
@ -286,11 +286,11 @@ int main() {
}
```
</spoiler>
</Spoiler>
## USACO Landscaping
<problems-list problems={metadata.problems.landscaping} />
<Problems problems={metadata.problems.landscaping} />
This looks similar to the previous task (we're moving dirt instead of fertilizer), so it's not too hard to guess that slope trick is applicable.
@ -300,7 +300,7 @@ Let $dp[i][j]$ equal the number of ways to move dirt around the first $i$ flower
### Full Solution
<spoiler title="Explanation">
<Spoiler title="Explanation">
This DP is concave up for any fixed $i$. To get $dp[i+1]$ from $dp[i]$ we must be able to support the following operations.
@ -318,9 +318,9 @@ As before, it helps to look at the differences $dif[j]=DP[j+1]-DP[j]$ instead. W
We can implement the last operation by updating all of the differences in the deques "lazily." This solution runs in $O(\sum A_i+\sum B_i)$ time.
</spoiler>
</Spoiler>
<spoiler title="My Solution">
<Spoiler title="My Solution">
```cpp
#include <bits/stdc++.h>
@ -359,7 +359,7 @@ int main() {
cout << ans << "\n";
}
```
</spoiler>
</Spoiler>
### Extension
@ -367,4 +367,4 @@ We can solve this problem when $\sum A_i+\sum B_i$ is not so small with lazy bal
## Problems
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />

View file

@ -35,14 +35,14 @@ partitioning into sqrt blocks (each block can have some sort of data structure .
optimization tips? (ez to get TLE with bad constant ..., can get AC with suboptimal complexity ...)
<problems-list problems={metadata.problems.fst} />
<Problems problems={metadata.problems.fst} />
## Mo's
<resources>
<resource source="CF" title="Mo's Algorithm" url="blog/entry/7383"></resource>
<resource source="CF" title="Mo's on Trees" url="blog/entry/43230"></resource>
</resources>
<Resources>
<Resource source="CF" title="Mo's Algorithm" url="blog/entry/7383"></Resource>
<Resource source="CF" title="Mo's on Trees" url="blog/entry/43230"></Resource>
</Resources>
[A2OJ](https://a2oj.com/category?ID=318)
@ -50,12 +50,12 @@ optimization tips? (ez to get TLE with bad constant ..., can get AC with subopti
### Block Tree
<problems-list problems={metadata.problems.block} />
<Problems problems={metadata.problems.block} />
<resources>
<resource source="CF" title="Block Tree" url="blog/entry/46843"></resource>
</resources>
<Resources>
<Resource source="CF" title="Block Tree" url="blog/entry/46843"></Resource>
</Resources>
### Train Tracking
<problems-list problems={metadata.problems.other} />
<Problems problems={metadata.problems.other} />

View file

@ -0,0 +1,90 @@
---
id: string-search
title: "String Searching"
author: Benjamin Qi
prerequisites:
- Silver - Depth First Search
description: Knuth-Morris-Pratt and Z Algorithms (and a few more related topics).
frequency: 1
---
export const metadata = {
problems: {
sample: [
new Problem("YS", "Set XOR-Min", "set_xor_min", "Easy", false, [], ""),
],
Z: [
new Problem("YS", "Z Algorithm", "zalgorithm", "Easy", false, [], ""),
new Problem("CF", "Concatenation with Intersection", "contest/1313/problem/E", "Hard", false, [], "")
],
pal: [
new Problem("ojuz", "Palindrome", "APIO14_palindrome", "Easy", false, [], ""),
]
}
};
## General
<Resources>
<Resource source="CPC" title="11 - Strings" url="11_strings">String Matching, KMP, Tries</Resource>
</Resources>
# Single String
## KMP
<Resources>
<Resource source="cp-algo" title="Prefix Function" url="prefix-function.html"></Resource>
<Resource source="PAPS" title="14.2 - String Matching"></Resource>
<Resource source="GFG" title="KMP Algorithm" url="searching-for-patterns-set-2-kmp-algorithm"></Resource>
<Resource source="TC" title="String Searching" url="introduction-to-string-searching-algorithms"></Resource>
</Resources>
## Z Algorithm
<Problems problems={metadata.problems.Z} />
<Resources>
<Resource source="cp-algo" title="Z Function" url="z-function.html"></Resource>
<Resource source="CPH" title="26.4 - Z-algorithm"></Resource>
<Resource source="CF" title="Z Algorithm" url="blog/entry/3107"></Resource>
</Resources>
## Manacher
<Resources>
<Resource source="HR" title="Manacher's Algorithm" url="https://www.hackerrank.com/topics/manachers-algorithm"></Resource>
<Resource source="CF" title="adamant - Manacher's algorithm and code readability" url="blog/entry/12143" starred>shorter code</Resource>
<Resource source="cp-algo" title="Manacher's Algorithm" url="string/manacher.html"></Resource>
</Resources>
# Multiple Strings
## Tries
<Problems problems={metadata.problems.sample} />
<Resources>
<Resource source="CPH" title="26.2"></Resource>
<Resource source="CF" title="Algorithm Gym" url="blog/entry/15729"></Resource>
<Resource source="PAPS" title="14.1 - Tries"></Resource>
</Resources>
## Aho-Corasick
<Resources>
<Resource source="cp-algo" title="Aho Corasick" url="string/aho_corasick.html"></Resource>
<Resource source="CF" title="adamant - Aho-Corasick" url="blog/entry/14854"></Resource>
<Resource source="GFG" title="Aho-Corasick for Pattern Searching" url="aho-corasick-algorithm-pattern-searching"></Resource>
</Resources>
## Palindromic Tree
<Problems problems={metadata.problems.pal} />
<Resources>
<Resource source="CF" title="adamant - Palindromic Tree" url="blog/entry/13959"></Resource>
</Resources>
DMOJ thing

View file

@ -33,49 +33,49 @@ export const metadata = {
## Resources
<resources>
<resource source="CF" title="Suffix Array" url="edu/course/2/lesson/2" starred>Videos & Practice Problems</resource>
<resource source="cp-algo" title="Suffix Array - Definition & Construction" url="suffix-array.html" starred></resource>
<resource source="CPC" title="11 - Strings (Suffix Array)" url="11_strings"></resource>
</resources>
<Resources>
<Resource source="CF" title="Suffix Array" url="edu/course/2/lesson/2" starred>Videos & Practice Problems</Resource>
<Resource source="cp-algo" title="Suffix Array - Definition & Construction" url="suffix-array.html" starred></Resource>
<Resource source="CPC" title="11 - Strings (Suffix Array)" url="11_strings"></Resource>
</Resources>
## Suffix Array
<problems-list problems={metadata.problems.sample} />
<Problems problems={metadata.problems.sample} />
### Implementations
<resources>
<resource source="Benq" title="Suffix Array w/ LCP" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/strings%20(14)/Light/SuffixArray%20(14.4).h">$O(N\log N)$</resource>
</resources>
<Resources>
<Resource source="Benq" title="Suffix Array w/ LCP" url="https://github.com/bqi343/USACO/blob/master/Implementations/content/strings%20(14)/Light/SuffixArray%20(14.4).h">$O(N\log N)$</Resource>
</Resources>
(recommend that you also test against brute force for many small strings)
## LCP Array
<problems-list problems={metadata.problems.lcpSam} />
<Problems problems={metadata.problems.lcpSam} />
Quickly compute longest common prefix of two suffixes.
<problems-list problems={metadata.problems.lcp} />
<Problems problems={metadata.problems.lcp} />
## Inverse Burrows-Wheeler
<resources>
<resource source="GFG" title="Inverting Burrows-Wheeler Transform" url="inverting-burrows-wheeler-transform">could be simpler?</resource>
</resources>
<Resources>
<Resource source="GFG" title="Inverting Burrows-Wheeler Transform" url="inverting-burrows-wheeler-transform">could be simpler?</Resource>
</Resources>
CSES Guide?
<problems-list problems={metadata.problems.burSam} />
<Problems problems={metadata.problems.burSam} />
## Run Enumerate
<resources>
<resource source="cp-algo" title="Finding repetitions" url="main_lorentz.html">could be simpler?</resource>
</resources>
<Resources>
<Resource source="cp-algo" title="Finding repetitions" url="main_lorentz.html">could be simpler?</Resource>
</Resources>
(describe how to do easily w/ suffix array)
<problems-list problems={metadata.problems.runSam} />
<Problems problems={metadata.problems.runSam} />

View file

@ -29,14 +29,14 @@ export const metadata = {
(what's line sweep?)
<resources>
<resource source="CPH" title="30.1, 30.2 - Sweep Line Algorithms"></resource>
<resource source="TC" title="Line Sweep Algorithms" url="line-sweep-algorithms"></resource>
</resources>
<Resources>
<Resource source="CPH" title="30.1, 30.2 - Sweep Line Algorithms"></Resource>
<Resource source="TC" title="Line Sweep Algorithms" url="line-sweep-algorithms"></Resource>
</Resources>
## Closest Pair
<problems-list problems={metadata.problems.closest} />
<Problems problems={metadata.problems.closest} />
(explanation? KACTL?)
@ -44,18 +44,18 @@ export const metadata = {
(refer to previous module)
<problems-list problems={metadata.problems.seg} />
<Problems problems={metadata.problems.seg} />
(filling in the details?)
## Manhattan MST
<problems-list problems={metadata.problems.manSam} />
<Problems problems={metadata.problems.manSam} />
(KACTL code)
explanation? topcoder prob has
<problems-list problems={metadata.problems.man} />
<Problems problems={metadata.problems.man} />
TC 760 ComponentsForever

View file

@ -24,25 +24,25 @@ export const metadata = {
## More Complex Operations
<resources>
<resource source="cp-algo" title="Operations on Polynomials & Series" url="algebra/polynomial.html"> </resource>
</resources>
<Resources>
<Resource source="cp-algo" title="Operations on Polynomials & Series" url="algebra/polynomial.html"> </Resource>
</Resources>
### Implementations
<resources>
<resource source="Benq" title="Polys" url="https://github.com/bqi343/USACO/tree/master/Implementations/content/numerical/Polynomials"> </resource>
</resources>
<Resources>
<Resource source="Benq" title="Polys" url="https://github.com/bqi343/USACO/tree/master/Implementations/content/numerical/Polynomials"> </Resource>
</Resources>
### Problems
<problems-list problems={metadata.problems.ys} />
<Problems problems={metadata.problems.ys} />
## Counting
No advanced knowledge about generating functions is required for either of these problems.
<problems-list problems={metadata.problems.general} />
<Problems problems={metadata.problems.general} />
- [zscoder GenFunc Pt 1](https://codeforces.com/blog/entry/77468)
- [zscoder GenFunc Pt 2](https://codeforces.com/blog/entry/77551)
@ -55,7 +55,7 @@ Of course, this will be split into several parts to make it easier to follow.
### Part 0: Includes
<warning-block>400+ lines of polynomial template</warning-block>
<Warning>400+ lines of polynomial template</Warning>
(link?)
@ -76,7 +76,7 @@ $$
We can naively implement this as follows. This gets MLE on F1, but at least it gives the correct results.
<spoiler title="Slow Solution">
<Spoiler title="Slow Solution">
```cpp
int n;
@ -113,7 +113,7 @@ int main() {
```
</spoiler>
</Spoiler>
### Part 2: Setting up a function to compute the same thing more quickly

View file

@ -6,9 +6,9 @@ description: "?"
frequency: 0
---
<info-block title="Pro Tip">
<Info title="Pro Tip">
Does not appear on USACO.
</info-block>
</Info>
* Tutorial
* [HackerRank](https://www.hackerrank.com/topics/game-theory-and-grundy-numbers)

View file

@ -54,7 +54,7 @@ export const metadata = {
## Link Cut Tree - Paths
<problems-list problems={metadata.problems.lctSam} />
<Problems problems={metadata.problems.lctSam} />
### Tutorial
@ -66,7 +66,7 @@ export const metadata = {
### Problems
<problems-list problems={metadata.problems.lct} />
<Problems problems={metadata.problems.lct} />
### USACO Camp
@ -81,7 +81,7 @@ export const metadata = {
## Link Cut Tree - Subtrees
<problems-list problems={metadata.problems.subSam} />
<Problems problems={metadata.problems.subSam} />
### Tutorial
@ -89,4 +89,4 @@ export const metadata = {
### Problems
<problems-list problems={metadata.problems.sub} />
<Problems problems={metadata.problems.sub} />

Some files were not shown because too many files have changed in this diff Show more