From 78d744c94b2ede45bd418dc5bcbb63380216209b Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 00:51:21 -0400 Subject: [PATCH 01/23] Update Code_Conventions.mdx --- content/1_Intro/Code_Conventions.mdx | 51 +++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/content/1_Intro/Code_Conventions.mdx b/content/1_Intro/Code_Conventions.mdx index 453804a..58f683e 100644 --- a/content/1_Intro/Code_Conventions.mdx +++ b/content/1_Intro/Code_Conventions.mdx @@ -14,6 +14,8 @@ Everything should compile assuming that the templates below are included. If any ## General +Note that these conventions mostly apply to `C++` and `Java`. + most material directly from this blog @@ -27,19 +29,52 @@ Everything should compile assuming that the templates below are included. If any - Use `++x` rather than `x++` to increment a variable (ie. in a `for` loop). - Start your `else` statement on the same line as the closing brace of your `if` statement, like so: - ```cpp - if (a == b) { - ++a; - } else { - ++b; - } - ``` + + + + +```cpp +if (a == b) { + ++a; +} else { + ++b; +} +``` + + + + + +```java +if (a == b) { + ++a; +} else { + ++b; +} +``` + + + + + +```python +if (a == b): + a += 1 +else + b += 1 +``` + + + + + - Use `true / false` for boolean values, not `1 / 0`. - Explain the use of any not well known standard library functions with comments that haven't been introduced before like `__builtin_ffs()` or `tie(a, b, c)` in C++. ## Template +The template is assumed to be in every code file. The word "template" usually refers to a C++ template as C++ templates can generally take advantange of more powerful features and be more customized by each competitor. Don't be afraid to write your own template! (Though the USACO Guide will assume the use of the following template) @@ -91,4 +126,4 @@ int main() { - \ No newline at end of file + From 20b1bb9895b7a3c9e2657fa1fbfd3beb247d56e8 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 00:51:55 -0400 Subject: [PATCH 02/23] Update Code_Conventions.mdx --- content/1_Intro/Code_Conventions.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/content/1_Intro/Code_Conventions.mdx b/content/1_Intro/Code_Conventions.mdx index 58f683e..b73d90b 100644 --- a/content/1_Intro/Code_Conventions.mdx +++ b/content/1_Intro/Code_Conventions.mdx @@ -75,6 +75,7 @@ else ## Template The template is assumed to be in every code file. The word "template" usually refers to a C++ template as C++ templates can generally take advantange of more powerful features and be more customized by each competitor. Don't be afraid to write your own template! (Though the USACO Guide will assume the use of the following template) + From 0845590c01b1df0468dd928829181897ef959ea1 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 00:52:54 -0400 Subject: [PATCH 03/23] Update DSU.mdx --- content/4_Gold/DSU.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/4_Gold/DSU.mdx b/content/4_Gold/DSU.mdx index cd6ead3..fa43afc 100644 --- a/content/4_Gold/DSU.mdx +++ b/content/4_Gold/DSU.mdx @@ -47,11 +47,11 @@ Note: You may prefer to use this in place of DFS for computing connected compone ## Implementations -Check PAPS for the explanation. `e[x]` contains the negation of the size of $x$'s component if $x$ is the representative of its component, and the parent of $x$ otherwise. - + +Check PAPS for the explanation. `e[x]` contains the negation of the size of $x$'s component if $x$ is the representative of its component, and the parent of $x$ otherwise. From 12a425070e7d04149aa475f89bb15339d6a424e1 Mon Sep 17 00:00:00 2001 From: Siyong Date: Sat, 18 Jul 2020 21:58:21 -0700 Subject: [PATCH 04/23] String Suffix + Problems in HLD and Centroid --- content/5_Plat/Centroid.mdx | 7 +- content/5_Plat/HLD.mdx | 3 +- content/6_Advanced/String_Suffix.mdx | 240 ++++++++++++++++++++++++++- 3 files changed, 245 insertions(+), 5 deletions(-) diff --git a/content/5_Plat/Centroid.mdx b/content/5_Plat/Centroid.mdx index c22b3a2..b15107f 100644 --- a/content/5_Plat/Centroid.mdx +++ b/content/5_Plat/Centroid.mdx @@ -15,6 +15,11 @@ export const metadata = { problems: { general: [ new Problem("CF", "Ciel the Commander", "problemset/problem/321/C", "Easy", false, ["Centroid"]), + new Problem("CF", "Sherlock's bet to Moriarty", "contest/776/problem/F", "Normal", false, ["Centroid"], ""), + new Problem("CF", "Digit Tree", "contest/715/problem/C", "Normal", false, ["Centroid", "NT"], ""), + new Problem("CF", "Double Tree", "contest/1140/problem/G", "Normal", false, ["Centroid", "DP"], ""), + new Problem("ojuz", "JOI - Factories", "JOI14_factories", "Normal", false, ["Centroid"], ""), + new Problem("CF", "Sum of Prefix Sums", contest/1303/problem/G", "Hard", false, ["Centroid", "CHT"], ""), new Problem("YS", "Frequency Table of Tree Distance", "frequency_table_of_tree_distance", "Hard", false, ["Centroid", "FFT"], ""), new Problem("DMOJ", "Bob Equilibrium", "dmopc19c7p6", "Hard", false, ["Centroid"], "tight time limit"), new Problem("DMOJ", "Time Traveller Imaxblue", "tc19summerh", "Hard", false, ["Centroid"], ""), @@ -35,4 +40,4 @@ export const metadata = { -*Note:* Unfortunately, it seems like constant factor is especially important for DMOJ. :| \ No newline at end of file +*Note:* Unfortunately, it seems like constant factor is especially important for DMOJ. :| diff --git a/content/5_Plat/HLD.mdx b/content/5_Plat/HLD.mdx index b9f04cf..3237ea3 100644 --- a/content/5_Plat/HLD.mdx +++ b/content/5_Plat/HLD.mdx @@ -24,6 +24,7 @@ export const metadata = { new Problem("HR", "Subtrees & Paths", "https://www.hackerrank.com/challenges/subtrees-and-paths", "Intro|Easy", false, ["HLD", "RURQ"], "See adamant's blog."), new Problem("YS","Vertex Set Path Composite","vertex_set_path_composite", "Intro|Normal", false, ["HLD", "SegTree"], "Function order matters! Maintain two segment trees, one for going up and the other for going down the tree."), new Problem("CF", "Tree Queries", "contest/1254/problem/D", "Hard", false, ["HLD"], "maybe hard to see why this applies here, gives $O(N\\log N)$ while most people solved it with some factor of $\\sqrt N$"), + new Problem("CF", "Two-Paths", "contest/1000/problem/G", "Hard", false, ["HLD"], ""), new Problem("ojuz", "JOI - Synchronization", "JOI13_synchronization", "Hard", false, ["HLD"], "$O(N\\log N)$ :D"), new Problem("ojuz", "JOI - Cats or Dogs", "JOI18_catdog", "Very Hard", false, ["HLD"], ""), ], @@ -49,4 +50,4 @@ export const metadata = { ## Problems - \ No newline at end of file + diff --git a/content/6_Advanced/String_Suffix.mdx b/content/6_Advanced/String_Suffix.mdx index 1cb8e58..9b51a13 100644 --- a/content/6_Advanced/String_Suffix.mdx +++ b/content/6_Advanced/String_Suffix.mdx @@ -1,20 +1,254 @@ --- id: string-suffix title: "String Suffix Structures" -author: Benjamin Qi +author: Benjamin Qi, Siyong Huang description: "?" prerequisites: - Platinum - String Searching frequency: 0 --- +export const metadata = { + problems: { + auto: [ + new Problem("Plat", "Standing Out from the Herd", "768", "Hard", false, [], ""), + ], + tree: [ + new Problem("CF", "Security", "contest/1037/problem/H", "Hard", false, ["Suffix Tree"], ""), + ] + } +}; + +## Suffix Automaton + +The **Suffix Automaton** is a directed acyclic word graph (DAWG), such that each path in the graph traces out a distinct substring of the original string. + +## Resources + + + Explanation of Suffix Automata + Excellent Suffix Automaton tutorial + + + + +Most problems can be solved with Suffix Arrays, Suffix Automata, or Suffix Trees. The solution may just be slightly easier/harder with the various data structures. + + + +## Problems + + + + + + + +```cpp +#include +#include +#include +#include + +FILE * IN, * OUT; +typedef long long ll; +const int MN = 1e5+10, MM = MN*2; +char s[MN]; +std::vector down[MM]; +int N, v[MM], c[MM][26], l[MM], d[MM], topo[MM], T, X; +ll f[MN], cnt[MM]; +bool u[MM]; + +/* +Key Variables: + +s: input strings +down: link tree of automaton +v: information regarding which cow each node belongs to +c: child array of automaton +l: link (of automaton) +d: depth (of automaton) +topo: toposort (of automaton) +T, X: counters for toposort and automaton +f: answer +cnt: number of ways to reach a node from the root +u: visited array for toposort +*/ + +//add cow b to value a +//value = -1: no cow assigned +//value = -2: multiple cows assigned +//value = 0..N: cow id +void merge(int& a, int b) +{ + if(!~a) a=b; + else if(~b&&a!=b) a=-2; +} + +//template automaton code +int append(int p, char x) +{ + if(~c[p][x]) + { + int q=c[p][x]; + if(d[q]==d[p]+1) + return q; + else + { + ++X; + for(int i=0;i<26;++i) c[X][i]=c[q][i]; + l[X]=l[q], d[X]=d[p]+1; + l[q]=X; + for(;~p&&c[p][x]==q;p=l[p]) + c[p][x]=l[q]; + return l[q]; + } + } + int n = ++X; + d[n]=d[p]+1; + for(;~p&&!~c[p][x];p=l[p]) + c[p][x]=n; + if(!~p) + l[n]=0; + else + { + int q=c[p][x]; + if(d[q]==d[p]+1) + l[n]=q; + else + { + ++X; + for(int i=0;i<26;++i) c[X][i]=c[q][i]; + l[X]=l[q], d[X]=d[p]+1; + l[n]=l[q]=X; + for(;~p&&c[p][x]==q;p=l[p]) + c[p][x]=l[q]; + } + } + return n; +} + +//DFS along links +void dfs2(int n=0) +{ + for(int x:down[n]) + { + dfs2(x); + merge(v[n], v[x]); + } +} +//DFS along suffix automaton. This builds the toposort +void dfs(int n=0) +{ + u[n]=1; + for(int i=0;i<26;++i) + { + int y=c[n][i]; + if(~y && !u[y]) dfs(y); + } + topo[T++] = n; +} + +int main(void) +{ + IN = fopen("standingout.in", "r"), OUT = fopen("standingout.out", "w"); + memset(v, -1, sizeof v); + memset(c, -1, sizeof c); + fscanf(IN, "%d", &N); + d[0]=0, l[0]=-1; + for(int i=0;i=0;--i) + { + x=topo[i]; + for(int j=0;j<26;++j) + if(~c[x][j]) + cnt[c[x][j]]+=cnt[x];//count number of paths from root to a node + if(v[x]>=0) + f[v[x]]+=cnt[x];//if this node is associated with a unique cow, add to answer + } + for(int i=0;i + +## Suffix Tree + +The **Suffix Tree** is a trie that contains all suffixes of a string. +Naively, this would take up $O(N^2)$ memory, but *path compression* enables it to be represented and computed in linear memory. + +## Resources + + + Explanation of Ukkonen's Suffix Tree Algorithm + Implementation of Ukkonen's Algorithm + + +## Generate Suffix Array + +A suffix array can be generated by the suffix tree by taking the dfs traversal of the suffix tree. + + + + + + + +```cpp +int N, sa[MN];//length of string, suffix array + +struct edge +{ +public: + int n, l, r;//node, edge covers s[l..r] + explicit operator bool() const {return n!=-1;} +} c[MN*2][26]; + +void dfs(int n=0, int d=0) +{ + bool c=0;// Has child. If false, then this node is a leaf + for(int i=0;i<26;++i) + if(c[n][i]) + { + c=1; + dfs(c[n][i].n, d+c[n][i].r-c[n][i].l); + } + if(!c) + sa[ctr++]=N-d; +} +``` + + + + +## Problems + + + * String Suffix Structures - * [Suffix Automata](http://codeforces.com/blog/entry/20861) * Suffix Tree - * [CF](http://codeforces.com/blog/entry/16780) + * [CF](https://codeforces.com/blog/entry/16780) * [CP-Algo](https://cp-algorithms.com/string/suffix-tree-ukkonen.html) * O(nlogn) suffix array usually suffices * More on Palindromic Tree * [Palindrome Partition](https://codeforces.com/contest/932/problem/G) * [Partial Solution](https://codeforces.com/blog/entry/19193) * [Palindromic Magic (HARD)](https://codeforces.com/contest/1081/problem/H) + From 36d5e785f4985bb238ae135da0b2069210640d26 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 01:00:54 -0400 Subject: [PATCH 05/23] Update Code_Conventions.mdx --- content/1_Intro/Code_Conventions.mdx | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/content/1_Intro/Code_Conventions.mdx b/content/1_Intro/Code_Conventions.mdx index b73d90b..41fc869 100644 --- a/content/1_Intro/Code_Conventions.mdx +++ b/content/1_Intro/Code_Conventions.mdx @@ -2,7 +2,7 @@ id: code-con title: Code Conventions author: Nathan Wang, Benjamin Qi, Michael Cao -description: "?" +description: "The conventions that this guide uses" prerequisites: - expected - modules @@ -10,7 +10,20 @@ prerequisites: The code we provide should follow the conventions below. Please note that you do _not_ have to copy our conventions; there is no "right" convention for coding! -Everything should compile assuming that the templates below are included. If any code does not compile or is hard to read, submit a complaint using the "Contact Us" button. +If any code does not compile or is hard to read, submit a complaint using the "Contact Us" button. + + + + +If you find unrecognizable symbols or functions in `C++` code, note the template below! Everything should compile assuming that the template below is included. + + + + + + + + ## General @@ -72,14 +85,14 @@ else - Use `true / false` for boolean values, not `1 / 0`. - Explain the use of any not well known standard library functions with comments that haven't been introduced before like `__builtin_ffs()` or `tie(a, b, c)` in C++. -## Template - -The template is assumed to be in every code file. The word "template" usually refers to a C++ template as C++ templates can generally take advantange of more powerful features and be more customized by each competitor. Don't be afraid to write your own template! (Though the USACO Guide will assume the use of the following template) - +## Template + +The "template" refers to code that is assumed to be in every file. The word "template" usually refers to a C++ template as C++ templates can generally take advantange of more powerful features and be more customized by each competitor. Don't be afraid to write your own template! The USACO Guide will assume the use of the following template in any C++ Code: + See [C++ Tips & Tricks](./cpp-tips). ```cpp From e69286bb2f19574d2d1cbe070f4868cf212c4dec Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 01:02:51 -0400 Subject: [PATCH 06/23] Update Code_Conventions.mdx --- content/1_Intro/Code_Conventions.mdx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/content/1_Intro/Code_Conventions.mdx b/content/1_Intro/Code_Conventions.mdx index 41fc869..1bbc9e4 100644 --- a/content/1_Intro/Code_Conventions.mdx +++ b/content/1_Intro/Code_Conventions.mdx @@ -10,12 +10,11 @@ prerequisites: The code we provide should follow the conventions below. Please note that you do _not_ have to copy our conventions; there is no "right" convention for coding! -If any code does not compile or is hard to read, submit a complaint using the "Contact Us" button. -If you find unrecognizable symbols or functions in `C++` code, note the template below! Everything should compile assuming that the template below is included. +If you find unrecognizable symbols or functions in `C++` code, note the template below; everything should compile assuming that the template below is included. @@ -25,6 +24,8 @@ If you find unrecognizable symbols or functions in `C++` code, note the template +If any code does not compile or is hard to read, submit a complaint using the "Contact Us" button. + ## General Note that these conventions mostly apply to `C++` and `Java`. @@ -91,7 +92,7 @@ else -The "template" refers to code that is assumed to be in every file. The word "template" usually refers to a C++ template as C++ templates can generally take advantange of more powerful features and be more customized by each competitor. Don't be afraid to write your own template! The USACO Guide will assume the use of the following template in any C++ Code: +The "template" refers to code that is assumed to be in every file. It is most often used in the context of C++, as C++ templates can generally take advantange of more powerful features and be more customized by each competitor. Don't be afraid to write your own template! The USACO Guide will assume the use of the following template in any C++ Code: See [C++ Tips & Tricks](./cpp-tips). From c3d79d6ae6a65d110b78c1d12c6bdbad2f2f29e0 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 01:05:20 -0400 Subject: [PATCH 07/23] Update Code_Conventions.mdx --- content/1_Intro/Code_Conventions.mdx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/content/1_Intro/Code_Conventions.mdx b/content/1_Intro/Code_Conventions.mdx index 1bbc9e4..b33b53c 100644 --- a/content/1_Intro/Code_Conventions.mdx +++ b/content/1_Intro/Code_Conventions.mdx @@ -18,9 +18,8 @@ If you find unrecognizable symbols or functions in `C++` code, note the template - - - + + @@ -69,16 +68,16 @@ if (a == b) { - + -```python +```py if (a == b): a += 1 else b += 1 ``` - + @@ -92,7 +91,7 @@ else -The "template" refers to code that is assumed to be in every file. It is most often used in the context of C++, as C++ templates can generally take advantange of more powerful features and be more customized by each competitor. Don't be afraid to write your own template! The USACO Guide will assume the use of the following template in any C++ Code: +The "template" refers to code that is assumed to be in every file. It is most often used in the context of C++, as C++ templates can generally take advantange of more powerful features and be more customized by each competitor. Don't be afraid to write your own template or don't use one at all! Regardless, The USACO Guide will assume the use of the following template in any C++ Code: See [C++ Tips & Tricks](./cpp-tips). From ab2f23749212b9ee81ac5e8289a296aed6fa5544 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 01:24:13 -0400 Subject: [PATCH 08/23] Update Code_Conventions.mdx --- content/1_Intro/Code_Conventions.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/1_Intro/Code_Conventions.mdx b/content/1_Intro/Code_Conventions.mdx index b33b53c..e55cb25 100644 --- a/content/1_Intro/Code_Conventions.mdx +++ b/content/1_Intro/Code_Conventions.mdx @@ -83,7 +83,8 @@ else - Use `true / false` for boolean values, not `1 / 0`. - - Explain the use of any not well known standard library functions with comments that haven't been introduced before like `__builtin_ffs()` or `tie(a, b, c)` in C++. + - Write comments to explain any uncommon library functions like the C++ functions `__builtin_ffs()` or `tie(a, b, c)`. + - Write comments to explain anything weird in general! :) From f2a6ac2409f20525ad4518c2ced74398b4d9817c Mon Sep 17 00:00:00 2001 From: Siyong Date: Sat, 18 Jul 2020 23:06:40 -0700 Subject: [PATCH 09/23] Updated String_Suffix and fixed Code_Conventions --- content/1_Intro/Code_Conventions.mdx | 20 +++++++++++--------- content/6_Advanced/String_Suffix.mdx | 24 ++++++++++++++++-------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/content/1_Intro/Code_Conventions.mdx b/content/1_Intro/Code_Conventions.mdx index e55cb25..35579e8 100644 --- a/content/1_Intro/Code_Conventions.mdx +++ b/content/1_Intro/Code_Conventions.mdx @@ -19,9 +19,10 @@ If you find unrecognizable symbols or functions in `C++` code, note the template + - + If any code does not compile or is hard to read, submit a complaint using the "Contact Us" button. @@ -53,11 +54,11 @@ if (a == b) { ++b; } ``` - + - + - + ```java if (a == b) { ++a; @@ -69,16 +70,16 @@ if (a == b) { - + ```py if (a == b): a += 1 else b += 1 ``` - + - + @@ -86,10 +87,10 @@ else - Write comments to explain any uncommon library functions like the C++ functions `__builtin_ffs()` or `tie(a, b, c)`. - Write comments to explain anything weird in general! :) - - ## Template + + The "template" refers to code that is assumed to be in every file. It is most often used in the context of C++, as C++ templates can generally take advantange of more powerful features and be more customized by each competitor. Don't be afraid to write your own template or don't use one at all! Regardless, The USACO Guide will assume the use of the following template in any C++ Code: @@ -139,6 +140,7 @@ int main() { + diff --git a/content/6_Advanced/String_Suffix.mdx b/content/6_Advanced/String_Suffix.mdx index 9b51a13..a4093c6 100644 --- a/content/6_Advanced/String_Suffix.mdx +++ b/content/6_Advanced/String_Suffix.mdx @@ -2,7 +2,7 @@ id: string-suffix title: "String Suffix Structures" author: Benjamin Qi, Siyong Huang -description: "?" +description: "Suffix Automata, Suffix Trees, and (TBD) Palindromic Trees" prerequisites: - Platinum - String Searching frequency: 0 @@ -23,7 +23,7 @@ export const metadata = { The **Suffix Automaton** is a directed acyclic word graph (DAWG), such that each path in the graph traces out a distinct substring of the original string. -## Resources +### Resources Explanation of Suffix Automata @@ -36,7 +36,7 @@ Most problems can be solved with Suffix Arrays, Suffix Automata, or Suffix Trees -## Problems +### Problems @@ -47,7 +47,6 @@ Most problems can be solved with Suffix Arrays, Suffix Automata, or Suffix Trees ```cpp #include #include -#include #include FILE * IN, * OUT; @@ -194,14 +193,18 @@ int main(void) The **Suffix Tree** is a trie that contains all suffixes of a string. Naively, this would take up $O(N^2)$ memory, but *path compression* enables it to be represented and computed in linear memory. -## Resources +### Resources Explanation of Ukkonen's Suffix Tree Algorithm Implementation of Ukkonen's Algorithm -## Generate Suffix Array +### Problems + + + +### Generate Suffix Array A suffix array can be generated by the suffix tree by taking the dfs traversal of the suffix tree. @@ -236,11 +239,16 @@ void dfs(int n=0, int d=0) ``` + + + + -## Problems +## Palindromic Tree + +(Still don't know what these are!! Benq help!) - * String Suffix Structures * Suffix Tree From c808e17f5f29911cddc21af2a3cf771191ef33f8 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 02:14:56 -0400 Subject: [PATCH 10/23] Update Fast_IO.mdx --- content/1_Intro/Fast_IO.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/1_Intro/Fast_IO.mdx b/content/1_Intro/Fast_IO.mdx index 96e1e37..f16189e 100644 --- a/content/1_Intro/Fast_IO.mdx +++ b/content/1_Intro/Fast_IO.mdx @@ -453,7 +453,7 @@ In general, it may be faster to store the answer all in a single `string` (C++) -The CF blog mentioned above notes that when printing many lines in C++, it may be faster to use the newline character `\n` in place of `endl`. Output streams in C++ (such as `cout` and `ofstream`) are buffered, meaning that they don't immediately print their output, but store some of it. At some point, the buffer's contents are written (i.e. "flushed") to the output device, whether it be the standard output stream or a file. Buffering the output helps with efficiency if accessing the output device (like a file) is slow. Because `endl` flushes the output, it may be faster to use `\n` instead and avoid unnecessary flushes. +The CF blog mentioned above notes that when printing many lines in C++, it may be faster to use the newline character `\n` in place of `endl`. Output streams in C++ (such as `cout` and `ofstream`) are buffered, meaning that they don't immediately print their output, but store some of it. At some point, the buffer's contents are written (i.e. "flushed") to the output device (e.g the standard output stream or a file). Buffering the output helps with efficiency if accessing the output device (like a file) is slow. Because `endl` flushes the output, it may be faster to use `\n` instead and avoid unnecessary flushes. From bc08a98d6527577fe09406d19fdaf15cc129a554 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 02:45:31 -0400 Subject: [PATCH 11/23] Update BFS.mdx --- content/4_Gold/BFS.mdx | 70 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/content/4_Gold/BFS.mdx b/content/4_Gold/BFS.mdx index 1f77bfd..e1549ce 100644 --- a/content/4_Gold/BFS.mdx +++ b/content/4_Gold/BFS.mdx @@ -102,8 +102,76 @@ int main() { + +Implementation of the CSAcademy article's problem in Java: +```java +import java.util.*; +import java.io.*; +class Main { + + static ArrayList edges[]; + static int dist[]; + static boolean visited[]; + + static void bfs(int startNode) { + Queue q = new ArrayDeque(); //You can choose any implementation of Queue (such as LinkedList), though I believe ArrayDeque is faster (?) + + q.add(startNode); + visited[startNode] = true; + dist[startNode] = 0; + + while(!q.isEmpty()) { + int currentNode = q.poll(); + + for(int adj : edges[currentNode]) { + if(!visited[adj]) { + visited[adj] = true; + dist[adj] = dist[currentNode]+1; + q.add(adj); + } + } + } + } + + public static void main (String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //Read about fast Java input in "Intro - Fast I/O" + + StringTokenizer st = new StringTokenizer(br.readLine()); + int N = Integer.parseInt(st.nextToken()); + int M = Integer.parseInt(st.nextToken()); + + int start = Integer.parseInt(st.nextToken()); + start--; + + edges = new ArrayList[N]; + dist = new int[N]; + visited = new boolean[N]; + for(int i = 0; i < N; i++) { + edges[i] = new ArrayList(); + dist[i] = -1; + } + + for(int i = 0; i < M; i++) { + st = new StringTokenizer(br.readLine()); + int a = Integer.parseInt(st.nextToken()); + int b = Integer.parseInt(st.nextToken()); + + a--; b--; + edges[a].add(b); + } + + bfs(start); + + PrintWriter pw = new PrintWriter(System.out); + + for(int i : dist) pw.print(i + " "); + pw.println(); + pw.close(); + } +} +``` @@ -144,4 +212,4 @@ Don't forget that once Bessie reaches the goal, she will ignore further commands ## Problems - \ No newline at end of file + From 55ac0a19a792f7bd6c7ef6324ba4f58e1c0619fd Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 02:50:00 -0400 Subject: [PATCH 12/23] Update BFS.mdx --- content/4_Gold/BFS.mdx | 76 +++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/content/4_Gold/BFS.mdx b/content/4_Gold/BFS.mdx index e1549ce..d960192 100644 --- a/content/4_Gold/BFS.mdx +++ b/content/4_Gold/BFS.mdx @@ -110,21 +110,21 @@ import java.util.*; import java.io.*; class Main { - + static ArrayList edges[]; static int dist[]; static boolean visited[]; - + static void bfs(int startNode) { Queue q = new ArrayDeque(); //You can choose any implementation of Queue (such as LinkedList), though I believe ArrayDeque is faster (?) - + q.add(startNode); visited[startNode] = true; dist[startNode] = 0; - + while(!q.isEmpty()) { int currentNode = q.poll(); - + for(int adj : edges[currentNode]) { if(!visited[adj]) { visited[adj] = true; @@ -134,39 +134,39 @@ class Main { } } } - - public static void main (String[] args) throws Exception { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //Read about fast Java input in "Intro - Fast I/O" - - StringTokenizer st = new StringTokenizer(br.readLine()); - int N = Integer.parseInt(st.nextToken()); - int M = Integer.parseInt(st.nextToken()); - - int start = Integer.parseInt(st.nextToken()); - start--; - - edges = new ArrayList[N]; - dist = new int[N]; - visited = new boolean[N]; - for(int i = 0; i < N; i++) { - edges[i] = new ArrayList(); - dist[i] = -1; - } - - for(int i = 0; i < M; i++) { - st = new StringTokenizer(br.readLine()); - int a = Integer.parseInt(st.nextToken()); - int b = Integer.parseInt(st.nextToken()); - - a--; b--; - edges[a].add(b); - } - - bfs(start); - - PrintWriter pw = new PrintWriter(System.out); - - for(int i : dist) pw.print(i + " "); + + public static void main (String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //Read about fast Java input in "Intro - Fast I/O" + + StringTokenizer st = new StringTokenizer(br.readLine()); + int N = Integer.parseInt(st.nextToken()); + int M = Integer.parseInt(st.nextToken()); + + int start = Integer.parseInt(st.nextToken()); + start--; + + edges = new ArrayList[N]; + dist = new int[N]; + visited = new boolean[N]; + for(int i = 0; i < N; i++) { + edges[i] = new ArrayList(); + dist[i] = -1; + } + + for(int i = 0; i < M; i++) { + st = new StringTokenizer(br.readLine()); + int a = Integer.parseInt(st.nextToken()); + int b = Integer.parseInt(st.nextToken()); + + a--; b--; + edges[a].add(b); + } + + bfs(start); + + PrintWriter pw = new PrintWriter(System.out); + + for(int i : dist) pw.print(i + " "); pw.println(); pw.close(); } From 433ae0c5beaa8c51701c379c4ea3e6fb5caf98f5 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 03:31:15 -0400 Subject: [PATCH 13/23] Update Code_Conventions.mdx --- content/1_Intro/Code_Conventions.mdx | 30 ++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/content/1_Intro/Code_Conventions.mdx b/content/1_Intro/Code_Conventions.mdx index 35579e8..9da9047 100644 --- a/content/1_Intro/Code_Conventions.mdx +++ b/content/1_Intro/Code_Conventions.mdx @@ -1,7 +1,7 @@ --- id: code-con title: Code Conventions -author: Nathan Wang, Benjamin Qi, Michael Cao +author: Nathan Wang, Benjamin Qi, Michael Cao, Nathan Chen description: "The conventions that this guide uses" prerequisites: - expected @@ -89,13 +89,15 @@ else ## Template +The "template" refers to code that is assumed to be in every file. + -The "template" refers to code that is assumed to be in every file. It is most often used in the context of C++, as C++ templates can generally take advantange of more powerful features and be more customized by each competitor. Don't be afraid to write your own template or don't use one at all! Regardless, The USACO Guide will assume the use of the following template in any C++ Code: +Templates in C++ can take advantange of more powerful features than the other contest languages, and they can be more customized to each competitor. Don't be afraid to write your own template or don't use one at all! Regardless, The USACO Guide will assume the use of the below template in any C++ Code. -See [C++ Tips & Tricks](./cpp-tips). +See [C++ Tips & Tricks](./cpp-tips) for explanations of the following code. ```cpp #include @@ -130,6 +132,8 @@ int main() { +Additional C++ Conventions: + - Avoid the use of macros (`#define`) other than those in the template above. - Use `const` in C++ for variables that don't change through the code. - Use `make_pair` rather than `{}` to store a pair. @@ -139,7 +143,25 @@ int main() { - + + +A normal Java template will contain a main method, helpful imports, and some form of I/O (for USACO, this would probably be File I/O) + +```java +import java.io.*; +import java.util.*; + +public class Main { //Name your program whatever you like. Note the class name must match the file name (e.g. this file would be "Main.java") + + public static void main(String[] args) throws Exception { //The code below reads from stdin and also uses a slow input method. Read "Intro - Fast I/O" for other Java I/O techniques. + Scanner sc = new Scanner(System.in); + PrintWriter pw = new PrintWriter(System.out); + } +} + +``` + + From ac7aae3b501028646a00150b2ec782eb0a150f46 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 03:33:42 -0400 Subject: [PATCH 14/23] Update Code_Conventions.mdx --- content/1_Intro/Code_Conventions.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/1_Intro/Code_Conventions.mdx b/content/1_Intro/Code_Conventions.mdx index 9da9047..ef100f0 100644 --- a/content/1_Intro/Code_Conventions.mdx +++ b/content/1_Intro/Code_Conventions.mdx @@ -148,8 +148,8 @@ Additional C++ Conventions: A normal Java template will contain a main method, helpful imports, and some form of I/O (for USACO, this would probably be File I/O) ```java -import java.io.*; -import java.util.*; +import java.io.*; //Imports necessary classes to read and write files +import java.util.*; //Imports many useful data structures and algorithms libraries public class Main { //Name your program whatever you like. Note the class name must match the file name (e.g. this file would be "Main.java") From 8851ff6a59e2da5a5de611a516206b723b5832c4 Mon Sep 17 00:00:00 2001 From: Siyong Date: Sun, 19 Jul 2020 00:43:55 -0700 Subject: [PATCH 15/23] Wrote out Centroid, Added to Custom_Cpp_STL also added problem to func_graphs but it will probably be taken out as I am still unable to solve it even after being told solution --- content/3_Silver/Custom_Cpp_STL.mdx | 46 +++++++++++++++++++--- content/3_Silver/Func_Graphs.mdx | 25 ++++++++---- content/5_Plat/Centroid.mdx | 60 +++++++++++++++++++++++++++-- 3 files changed, 115 insertions(+), 16 deletions(-) diff --git a/content/3_Silver/Custom_Cpp_STL.mdx b/content/3_Silver/Custom_Cpp_STL.mdx index 7e6fb3b..c6498e9 100644 --- a/content/3_Silver/Custom_Cpp_STL.mdx +++ b/content/3_Silver/Custom_Cpp_STL.mdx @@ -5,7 +5,7 @@ author: Siyong Huang, Benjamin Qi prerequisites: - sorting-custom - intro-ordered -description: "?" +description: "More ways to write custom comparators in C++ and incorporating them into STL objects." frequency: 1 --- @@ -43,7 +43,6 @@ int main() { } ``` - ## Comparator ```cpp @@ -67,10 +66,20 @@ int main() { } ``` + + +You can also use the following syntax to declare set `v` using a function + +`set v(cmp);` + + + Lambda expressions also work: ```cpp auto cmp = [](const Edge& x, const Edge& y) { return x.w < y.w; }; +//The real type of cmp is function +//auto is used for short int main() { int M = 4; @@ -83,7 +92,13 @@ int main() { } ``` -In this case, we can shorten the declaration of `v` by writing `set v(cmp);` instead. + + +You can also use the following syntax to declare set `v` using a lambda + +`set v(cmp);` + + ## Functors @@ -127,9 +142,17 @@ int main() { } ``` + + +One functor can be used for multiple objects. Just keep overloading the `()` operator! + + + ## Built-In Functors -Overloading the less than operator (`<`) automatically generates the functor `less`. Similarly, overloading `>` automatically generates the functor [`greater`](https://en.cppreference.com/w/cpp/utility/functional/greater). We can use this to store a set in reverse order. +Overloading the less than operator (`<`) automatically generates the functor [`less`](https://en.cppreference.com/w/cpp/utility/functional/less). +Similarly, overloading (`>`) automatically generates the functor [`greater`](https://en.cppreference.com/w/cpp/utility/functional/greater). +We can use this to store a set in reverse order. ```cpp #include @@ -166,4 +189,17 @@ The following are all valid: set> a; map> b; priority_queue,greater> c; -``` \ No newline at end of file +``` + + + +In C++, priority queues are sorted in decreasing order. +Specifically, larger elements have higher 'priority' and are popped first. + +If you want smaller elements to be at the front of the queue, two ways are listed below + +1. Overload the (`<`) operator to output the opposite effect. + +2. Overload the (`>`) operator properly and use the (`greater`) functor. + + diff --git a/content/3_Silver/Func_Graphs.mdx b/content/3_Silver/Func_Graphs.mdx index 19928ce..91e4e3d 100644 --- a/content/3_Silver/Func_Graphs.mdx +++ b/content/3_Silver/Func_Graphs.mdx @@ -24,23 +24,29 @@ export const metadata = { new Problem("POI", "Mafia", "https://szkopul.edu.pl/problemset/problem/w3YAoAT3ej27YeiaNWjK57_G/site/?key=statement", "Hard", false, ["Func Graph"], ""), new Problem("POI", "Spies", "https://szkopul.edu.pl/problemset/problem/r6tMTfvQFPAEfQioYMCQndQe/site/?key=statement", "Hard", false, [], ""), new Problem("POI", "Frog", "https://szkopul.edu.pl/problemset/problem/qDH9CkBHZKHY4vbKRBlXPrA7/site/?key=statement", "Hard", false, [], ""), + new Problem("ojuz", "Space Pirate", "JOI14_space_pirate", "Very Hard", false, ["Graphs"], "One of the most difficult problems of all time. Build a tree with a single back edge. Break into three cases: path -> other cycle, path -> subtree, path -> non-subtree. Then perform some black magic."), ], } }; +## Functional Graphs + We'll consider graphs like the one presented in this problem: < br/> -Aka **successor graph**. +In a **functional graph**, each node has exactly one out-edge. +This is also commonly referred to as a **successor graph**. + +### Resources -## Implementation +### Implementation The following sample code counts the number of cycles in such a graph. The "stack" contains nodes that can reach the current node. If the current node points to a node `v` on the stack (`on_stack[v]` is true), then we know that a cycle has been created. However, if the current node points to a node `v` that has been previously visited but is not on the stack, then we know that the current chain of nodes points into a cycle that has already been considered. @@ -82,6 +88,14 @@ int main() **Floyd's Algorithm**, also commonly referred to as the **Tortoise and Hare Algorithm**, is capable of detecting cycles in a functional graph in $O(N)$ time and $O(1)$ memory (not counting the graph itself) +### Resources + + + + + +### Implementation + ```cpp //UNTESTED pair detect_cycle(int *next, int start_node) //return pair(length of cycle, distance from start node to in cycle) @@ -105,12 +119,7 @@ pair detect_cycle(int *next, int start_node) //return pair(length of c } ``` - - - - - -## Problems +### Problems diff --git a/content/5_Plat/Centroid.mdx b/content/5_Plat/Centroid.mdx index b15107f..ee04b74 100644 --- a/content/5_Plat/Centroid.mdx +++ b/content/5_Plat/Centroid.mdx @@ -1,7 +1,7 @@ --- id: centroid title: "Centroid Decomposition" -author: Benjamin Qi +author: Benjamin Qi, Siyong Huang prerequisites: - dfs - SRQ @@ -14,12 +14,12 @@ import { Problem } from "../models"; export const metadata = { problems: { general: [ - new Problem("CF", "Ciel the Commander", "problemset/problem/321/C", "Easy", false, ["Centroid"]), + new Problem("CF", "Ciel the Commander", "problemset/problem/321/C", "Easy", false, ["Centroid"], ""), new Problem("CF", "Sherlock's bet to Moriarty", "contest/776/problem/F", "Normal", false, ["Centroid"], ""), new Problem("CF", "Digit Tree", "contest/715/problem/C", "Normal", false, ["Centroid", "NT"], ""), new Problem("CF", "Double Tree", "contest/1140/problem/G", "Normal", false, ["Centroid", "DP"], ""), new Problem("ojuz", "JOI - Factories", "JOI14_factories", "Normal", false, ["Centroid"], ""), - new Problem("CF", "Sum of Prefix Sums", contest/1303/problem/G", "Hard", false, ["Centroid", "CHT"], ""), + new Problem("CF", "Sum of Prefix Sums", "contest/1303/problem/G", "Hard", false, ["Centroid", "CHT"], ""), new Problem("YS", "Frequency Table of Tree Distance", "frequency_table_of_tree_distance", "Hard", false, ["Centroid", "FFT"], ""), new Problem("DMOJ", "Bob Equilibrium", "dmopc19c7p6", "Hard", false, ["Centroid"], "tight time limit"), new Problem("DMOJ", "Time Traveller Imaxblue", "tc19summerh", "Hard", false, ["Centroid"], ""), @@ -29,6 +29,12 @@ export const metadata = { } }; +## Centroid Decomposition + +**Centroid Decomposition** is a divide and conquer technique for trees. +The **centroid** of a tree is a node which, if rooted, results in no other nodes having a subtree of size greater than $\frac{N}{2}$. +**Centroid Decomposition** works by repeated splitting the tree and each of the resulting subgraphs at the centroid, producing $O(\log N)$ layers of subgraphs. + ### Tutorial @@ -36,6 +42,54 @@ export const metadata = { +### Implementation + + + + + + + +```cpp +bool r[MN];//removed +int s[MN];//subtree size +int dfs(int n, int p = 0) +{ + s[n] = 1; + for(int x : a[n]) + if(x != p && !r[x]) + s[n] += dfs(x, n); + return s[n]; +} +int get_centroid(int n, int ms, int p = 0)//n = node, ms = size of tree, p = parent +{ + for(int x : a[n]) + if(x != p && !r[x]) + if(s[x]*2 > ms) + return get_centroid(x, ms, n); + return n; +} +void centroid(int n = 1) +{ + int C = get_centroid(n, dfs(n)); + + //do something + + r[C] = 1; + for(int x : a[C]) + if(!r[x]) + centroid(x); +} +``` + + + + + + + + + ### Problems From 8f3549271da3a51ab53e1c5c637b3c287d23d645 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 04:11:19 -0400 Subject: [PATCH 16/23] Update Running_Code.mdx --- content/1_Intro/Running_Code.mdx | 55 ++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/content/1_Intro/Running_Code.mdx b/content/1_Intro/Running_Code.mdx index 066df93..f696a27 100644 --- a/content/1_Intro/Running_Code.mdx +++ b/content/1_Intro/Running_Code.mdx @@ -1,7 +1,7 @@ --- id: running-code title: Running Code -author: Benjamin Qi, Hankai Zhang, Anthony Wang, Nathan Wang +author: Benjamin Qi, Hankai Zhang, Anthony Wang, Nathan Wang, Nathan Chen description: Options for running your language of choice. prerequisites: - choosing-lang @@ -42,7 +42,7 @@ You can also share code with [pastebin](https://pastebin.com/) or [hastebin](htt -You can run from the command line and use a text editor of your choice. +You can run your C++ programs from the command line and use a text editor of your choice. Read below for different options to create and run C++ programs. ## Text Editors @@ -269,6 +269,57 @@ Now you can easily compile and run `name.cpp` from the command line with `co nam + + +First, download the [JDK](https://docs.oracle.com/en/java/javase/14/install/overview-jdk-installation.html#GUID-8677A77F-231A-40F7-98B9-1FD0B48C346A). Then, test that you can use the right commands. + +On Windows, open `cmd` and type the following command into the prompt: + +``` +java +``` + +If you get the below result, you may have to add the JDK to your [PATH](https://docs.oracle.com/en/java/javase/14/install/installation-jdk-microsoft-windows-platforms.html#GUID-A7E27B90-A28D-4237-9383-A58B416071CA) variable. + +``` +'java' is not recognized as an internal or external comman, +operable program or batch file +``` + +If you get a list of command arguments to the `java` command, then you're probably good to go. + + + +What do you have to do on Mac to get Java working the command line? + + + +Running a Java file off of the command-line is relatively simple after the JDK is downloaded. + +Consider this code of `Main.java` and assume it is in a file on your computer: + +```java +public class Main { + public static void main(String[] args) { + System.out.println("Hello World!"); + } +} +``` + +Use the `cd` command to get to the directory that contains `Main.java`. Then, run the following command to compile the code: +``` +javac Main.java +``` +If it runs successfully, a file called `Main.class` will show up in the same directory, which can be executed with the next command: +``` +java Main +``` +If everything goes accordingly, the console should output `Hello World!`. + +If you do USACO-style file I/O, meaning that files are in the "local directory", then the files must be located in the same directory as the source code (if you use the above method). + + + Download Python through [the official website](https://python.org). On Windows and Mac, you can download executable files directly; on Linux, you must either download the Python source code and compile from source, or obtain Python through your package manager. From b43fee37f8749e7d4571a1de01c74bdb2900ea3e Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 04:13:37 -0400 Subject: [PATCH 17/23] Update Running_Code.mdx --- content/1_Intro/Running_Code.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/1_Intro/Running_Code.mdx b/content/1_Intro/Running_Code.mdx index f696a27..a9dc6c0 100644 --- a/content/1_Intro/Running_Code.mdx +++ b/content/1_Intro/Running_Code.mdx @@ -286,7 +286,7 @@ If you get the below result, you may have to add the JDK to your [PATH](https:// operable program or batch file ``` -If you get a list of command arguments to the `java` command, then you're probably good to go. +If you get a list of command arguments for the `java` command, you're probably good to go. @@ -306,7 +306,7 @@ public class Main { } ``` -Use the `cd` command to get to the directory that contains `Main.java`. Then, run the following command to compile the code: +Use the `cd` command on your console to get to the directory that contains `Main.java`. Then, run the following command to compile the code: ``` javac Main.java ``` From ddb4715b0ef01c8bdcfb68b4f5d96ae8e618f2ed Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 04:50:14 -0400 Subject: [PATCH 18/23] Update TopoSort.mdx --- content/4_Gold/TopoSort.mdx | 120 ++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 4 deletions(-) diff --git a/content/4_Gold/TopoSort.mdx b/content/4_Gold/TopoSort.mdx index 48c9b5b..d5c2998 100644 --- a/content/4_Gold/TopoSort.mdx +++ b/content/4_Gold/TopoSort.mdx @@ -1,7 +1,7 @@ --- id: toposort title: "Topological Sort" -author: Benjamin Qi, Michael Cao +author: Benjamin Qi, Michael Cao, Nathan Chen prerequisites: - Gold - Breadth First Search - Gold - Introduction to Dynamic Programming @@ -84,9 +84,121 @@ $$ or zero if $v$ has in-degree $0$. If we process the states in topological order, it is guarangeed that $dp[u]$ will already have been computed before computing $dp[v]$. -(implementation?) + - + + + ```cpp + #include + +using namespace std; + +int prev_flight[100000]; +int dist[100000]; +int in_degree[100000]; +vector edge[100000]; +vector backEdge[100000]; + +int N, M; + +//Does a topological sort +void compute() { + queue q; + for(int i = 0; i < N; i++) { + if(in_degree[i] == 0) { + q.push(i); + } + } + + while(!q.empty()) { + int node = q.front(); + q.pop(); + + for(int next : edge[node]) { + in_degree[next]--; + if(in_degree[next] == 0) q.push(next); + } + + //The below block computes the DP + int mx = -999999999; + int mx_node = -1; + for(int prev : backEdge[node]) { + if(dist[prev] + 1 > mx) { + mx = dist[prev] + 1; + mx_node = prev; + } + } + + dist[node] = mx; + if(node == 0) dist[node] = 1; + prev_flight[node] = mx_node; + } + +} + +int main() { + ios_base::sync_with_stdio(false); + cin.tie(NULL); + + cin >> N >> M; + + for(int i = 0; i < N; i++) { + prev_flight[i] = -1; + dist[i] = -999999999; + in_degree[i] = 0; + } + + for(int i = 0; i < M; i++) { + int a, b; + cin >> a >> b; + a--, b--; + in_degree[b]++; + edge[a].push_back(b); + + backEdge[b].push_back(a); + } + + compute(); + + stack answer; + int temp = N-1; + + bool contains0 = false; + if(temp == 0) contains0 = true; + + while(temp != -1 && dist[temp] >= 0) { + answer.push(temp); + temp = prev_flight[temp]; + if(temp == 0) contains0 = true; + } + + if(contains0) { + cout << dist[N-1] << "\n"; + while(!answer.empty()) { + cout << answer.top()+1; + answer.pop(); + if(!answer.empty()) cout << " "; + } + cout << "\n"; + } else { + cout << "IMPOSSIBLE\n"; + } + + return 0; +} + ``` + + + + + + ```java + a + ``` + + + + @@ -96,4 +208,4 @@ or zero if $v$ has in-degree $0$. If we process the states in topological order, ## Problems - \ No newline at end of file + From 1e3fb6fd3eb08267b0d62ebd8dd2f6e45ed006c0 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 04:54:03 -0400 Subject: [PATCH 19/23] Update TopoSort.mdx --- content/4_Gold/TopoSort.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/4_Gold/TopoSort.mdx b/content/4_Gold/TopoSort.mdx index d5c2998..b7abe74 100644 --- a/content/4_Gold/TopoSort.mdx +++ b/content/4_Gold/TopoSort.mdx @@ -82,7 +82,7 @@ $$ dp[v]=\max_{\text{edge } u\to v \text{ exists}}dp[u]+1, $$ -or zero if $v$ has in-degree $0$. If we process the states in topological order, it is guarangeed that $dp[u]$ will already have been computed before computing $dp[v]$. +or $1$ if $v$ is node $1$. If we process the states in topological order, it is guaranteed that $dp[u]$ will already have been computed before computing $dp[v]$. From e74639fad6f6f6128a14676845980454f5ee4fb0 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 04:57:57 -0400 Subject: [PATCH 20/23] Update TopoSort.mdx --- content/4_Gold/TopoSort.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/4_Gold/TopoSort.mdx b/content/4_Gold/TopoSort.mdx index b7abe74..470e6a2 100644 --- a/content/4_Gold/TopoSort.mdx +++ b/content/4_Gold/TopoSort.mdx @@ -136,7 +136,7 @@ void compute() { } -int main() { +int main() { //See "Intro - Fast I/O" for more information about the first two lines in the main function ios_base::sync_with_stdio(false); cin.tie(NULL); From de962f9b5786efcb25ced133627668c3086d0815 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 05:12:49 -0400 Subject: [PATCH 21/23] Update TopoSort.mdx --- content/4_Gold/TopoSort.mdx | 185 +++++++++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 1 deletion(-) diff --git a/content/4_Gold/TopoSort.mdx b/content/4_Gold/TopoSort.mdx index 470e6a2..04d915b 100644 --- a/content/4_Gold/TopoSort.mdx +++ b/content/4_Gold/TopoSort.mdx @@ -193,7 +193,190 @@ int main() { //See "Intro - Fast I/O" for more information about the first two l ```java - a +import java.util.*; +import java.io.*; + +//longest_path +public class Main { + + static int prev_flight[], dist[], in_degree[]; + static ArrayList edge[]; + static ArrayList backEdge[]; + + static int N, M; + + //does a topological sort + static void compute() { + Queue q = new ArrayDeque(); + for(int i = 0; i < N; i++) { + if(in_degree[i] == 0) { + q.add(i); + } + } + + while(!q.isEmpty()) { + int node = q.poll(); + + for(int next : edge[node]) { + in_degree[next]--; + if(in_degree[next] == 0) q.add(next); + } + + //The below block computes the DP + int mx = -999999999; + int mx_node = -1; + for(int prev : backEdge[node]) { + if(dist[prev] + 1 > mx) { + mx = dist[prev] + 1; + mx_node = prev; + } + } + + dist[node] = mx; + if(node == 0) dist[node] = 1; + prev_flight[node] = mx_node; + } + } + + public static void main(String[] args) throws Exception { + FastIO sc = new FastIO(System.in); //View "Intro - Fast I/O" for more information about the "FastIO" class + + N = sc.nextInt(); + M = sc.nextInt(); + + prev_flight = new int[N]; + dist = new int[N]; + in_degree = new int[N]; + edge = new ArrayList[N]; + backEdge = new ArrayList[N]; + + for(int i = 0; i < N; i++) { + prev_flight[i] = -1; + dist[i] = -999999999; + in_degree[i] = 0; + edge[i] = new ArrayList(); + backEdge[i] = new ArrayList(); + } + + for(int i = 0; i < M; i++) { + int a = sc.nextInt(), b = sc.nextInt(); + a--; b--; + in_degree[b]++; + edge[a].add(b); + backEdge[b].add(a); + } + + compute(); + + PrintWriter pw = new PrintWriter(System.out); + + ArrayDeque answer = new ArrayDeque(); //Acts as a Stack + int temp = N-1; + + boolean contains0 = false; + if(temp == 0) contains0 = true; + + while(temp != -1 && dist[temp] >= 0) { + answer.push(temp); + temp = prev_flight[temp]; + if(temp == 0) contains0 = true; + } + + if(contains0) { + pw.println(dist[N-1]); + while(!answer.isEmpty()) { + pw.print(answer.peekFirst()+1); + answer.pop(); + if(!answer.isEmpty()) pw.print(" "); + } + pw.println(); + } else { + pw.println("IMPOSSIBLE\n"); + } + pw.close(); + } + + //practically a necessity for Java users on CSES + static class FastIO { + + InputStream dis; + byte[] buffer = new byte[1 << 17]; + int pointer = 0; + + public FastIO(String fileName) throws Exception { + dis = new FileInputStream(fileName); + } + + public FastIO(InputStream is) throws Exception { + dis = is; + } + + int nextInt() throws Exception { + int ret = 0; + + byte b; + do { + b = nextByte(); + } while (b <= ' '); + boolean negative = false; + if (b == '-') { + negative = true; + b = nextByte(); + } + while (b >= '0' && b <= '9') { + ret = 10 * ret + b - '0'; + b = nextByte(); + } + + return (negative) ? -ret : ret; + } + + long nextLong() throws Exception { + long ret = 0; + + byte b; + do { + b = nextByte(); + } while (b <= ' '); + boolean negative = false; + if (b == '-') { + negative = true; + b = nextByte(); + } + while (b >= '0' && b <= '9') { + ret = 10 * ret + b - '0'; + b = nextByte(); + } + + return (negative) ? -ret : ret; + } + + byte nextByte() throws Exception { + if (pointer == buffer.length) { + dis.read(buffer, 0, buffer.length); + pointer = 0; + } + return buffer[pointer++]; + } + + String next() throws Exception { + StringBuffer ret = new StringBuffer(); + + byte b; + do { + b = nextByte(); + } while (b <= ' '); + while (b > ' ') { + ret.appendCodePoint(b); + b = nextByte(); + } + + return ret.toString(); + } + + } +} + ``` From 4c122416c1328ed852e6de6808d089a72a76de43 Mon Sep 17 00:00:00 2001 From: nchn27 <46332369+nchn27@users.noreply.github.com> Date: Sun, 19 Jul 2020 05:20:52 -0400 Subject: [PATCH 22/23] Update TopoSort.mdx --- content/4_Gold/TopoSort.mdx | 72 +++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/content/4_Gold/TopoSort.mdx b/content/4_Gold/TopoSort.mdx index 04d915b..83e2908 100644 --- a/content/4_Gold/TopoSort.mdx +++ b/content/4_Gold/TopoSort.mdx @@ -40,7 +40,7 @@ A [topological sort](https://en.wikipedia.org/wiki/Topological_sorting) of a dir ## Tutorial - both BFS, DFS + The algorithms to find a topological sort are based on BFS and DFS. ### DFS @@ -58,7 +58,73 @@ A [topological sort](https://en.wikipedia.org/wiki/Topological_sorting) of a dir The BFS version, known as [Kahn's Algorithm](https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm), makes it obvious how to extract the lexicographically minimum topological sort. -(implementation) + + + + +```cpp +int in_degree[100000]; +vector edge[100000]; + +int N; //number of nodes + +void compute() { + queue q; + for(int i = 0; i < N; i++) { + if(in_degree[i] == 0) { + q.push(i); + } + } + + while(!q.empty()) { + int node = q.front(); + q.pop(); + + for(int next : edge[node]) { + in_degree[next]--; + if(in_degree[next] == 0) q.push(next); + } + + //[put problem-specific processing here] + } + +} +``` + + + + + +```java + static int in_degree[]; + static ArrayList edge[]; //adjacency list + + static int N; //number of nodes + + static void topological_sort() { + Queue q = new ArrayDeque(); + for(int i = 0; i < N; i++) { + if(in_degree[i] == 0) { + q.add(i); + } + } + + while(!q.isEmpty()) { + int node = q.poll(); + + for(int next : edge[node]) { + in_degree[next]--; + if(in_degree[next] == 0) q.add(next); + } + + //[put problem-specific processing here] + } + } +``` + + + + @@ -84,6 +150,8 @@ $$ or $1$ if $v$ is node $1$. If we process the states in topological order, it is guaranteed that $dp[u]$ will already have been computed before computing $dp[v]$. +Note that the implementation of this idea below uses Kahn's algorithm for topological sorting: + From e351215b68e4836f2e5dea85aceae6f8de1007f8 Mon Sep 17 00:00:00 2001 From: Benjamin Qi Date: Sun, 19 Jul 2020 11:43:50 -0400 Subject: [PATCH 23/23] trees, fix toposort --- content/4_Gold/DP_Trees.mdx | 1 + content/4_Gold/TopoSort.mdx | 10 +++++----- content/5_Plat/Centroid.mdx | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/content/4_Gold/DP_Trees.mdx b/content/4_Gold/DP_Trees.mdx index 32f65db..c4aa8e3 100644 --- a/content/4_Gold/DP_Trees.mdx +++ b/content/4_Gold/DP_Trees.mdx @@ -27,6 +27,7 @@ export const metadata = { new Problem("Plat", "Delegation", "1020", "Hard", false, ["DP", "Binary Search"], ""), new Problem("CF", "Ostap & Tree", "problemset/problem/735/E", "Hard", false, ["DP"], "$O(NK)$ I think"), new Problem("CSES", "Creating Offices", "1752", "Hard", false, ["Greedy"], "equivalent to BOI - Cat in a Tree"), + new Problem("Plat", "Cow At Large", "793", "Hard", false, [], "This is not too hard to fakesolve. First write an (optimized?) O(N^2) DP to pass test cases 1-6. This won't work for test cases 7-11, but in these test cases all trees have at most 20 leaves. Therefore it suffices to compress tree edges (repeatedly remove vertices of degree 2) and run the same solution. For a legit DP solution, see Eric Zhang's comment here: https://codeforces.com/blog/entry/57170?#comment-410179"), ], } } diff --git a/content/4_Gold/TopoSort.mdx b/content/4_Gold/TopoSort.mdx index 83e2908..4621229 100644 --- a/content/4_Gold/TopoSort.mdx +++ b/content/4_Gold/TopoSort.mdx @@ -155,9 +155,9 @@ Note that the implementation of this idea below uses Kahn's algorithm for topolo - - ```cpp - #include + +```cpp +#include using namespace std; @@ -259,8 +259,8 @@ int main() { //See "Intro - Fast I/O" for more information about the first two l - - ```java + +```java import java.util.*; import java.io.*; diff --git a/content/5_Plat/Centroid.mdx b/content/5_Plat/Centroid.mdx index b15107f..d4cf8d6 100644 --- a/content/5_Plat/Centroid.mdx +++ b/content/5_Plat/Centroid.mdx @@ -19,7 +19,7 @@ export const metadata = { new Problem("CF", "Digit Tree", "contest/715/problem/C", "Normal", false, ["Centroid", "NT"], ""), new Problem("CF", "Double Tree", "contest/1140/problem/G", "Normal", false, ["Centroid", "DP"], ""), new Problem("ojuz", "JOI - Factories", "JOI14_factories", "Normal", false, ["Centroid"], ""), - new Problem("CF", "Sum of Prefix Sums", contest/1303/problem/G", "Hard", false, ["Centroid", "CHT"], ""), + new Problem("CF", "Sum of Prefix Sums", "contest/1303/problem/G", "Hard", false, ["Centroid", "CHT"], ""), new Problem("YS", "Frequency Table of Tree Distance", "frequency_table_of_tree_distance", "Hard", false, ["Centroid", "FFT"], ""), new Problem("DMOJ", "Bob Equilibrium", "dmopc19c7p6", "Hard", false, ["Centroid"], "tight time limit"), new Problem("DMOJ", "Time Traveller Imaxblue", "tc19summerh", "Hard", false, ["Centroid"], ""),