From 0a5fd544ac386d838bc2d912d5f68c23d8ba88c8 Mon Sep 17 00:00:00 2001 From: Nathan Wang Date: Sun, 19 Jul 2020 09:37:27 -0700 Subject: [PATCH 1/8] add some functionality to dashboard --- src/components/Dashboard/ActiveItems.tsx | 0 src/components/Dashboard/DashboardNav.tsx | 0 src/components/Dashboard/WelcomeBackBanner.tsx | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/components/Dashboard/ActiveItems.tsx create mode 100644 src/components/Dashboard/DashboardNav.tsx create mode 100644 src/components/Dashboard/WelcomeBackBanner.tsx diff --git a/src/components/Dashboard/ActiveItems.tsx b/src/components/Dashboard/ActiveItems.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Dashboard/DashboardNav.tsx b/src/components/Dashboard/DashboardNav.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Dashboard/WelcomeBackBanner.tsx b/src/components/Dashboard/WelcomeBackBanner.tsx new file mode 100644 index 0000000..e69de29 From b9737def5310e8a6896a82c7a5c32e930034a894 Mon Sep 17 00:00:00 2001 From: Nathan Wang Date: Sun, 19 Jul 2020 09:38:13 -0700 Subject: [PATCH 2/8] add functionality to dashboard oops --- content/ordering.ts | 12 + src/components/Dashboard/ActiveItems.tsx | 89 ++++ src/components/Dashboard/DashboardNav.tsx | 213 ++++++++++ .../Dashboard/WelcomeBackBanner.tsx | 43 ++ src/context/UserDataContext.tsx | 90 ++-- src/pages/dashboard.tsx | 388 +++--------------- src/templates/moduleTemplate.tsx | 6 + 7 files changed, 490 insertions(+), 351 deletions(-) diff --git a/content/ordering.ts b/content/ordering.ts index 9aa1212..09567a0 100644 --- a/content/ordering.ts +++ b/content/ordering.ts @@ -304,3 +304,15 @@ SECTIONS.forEach(section => { }); export { moduleIDToSectionMap }; + +let moduleIDToURLMap: {[key: string]: string} = {}; + +SECTIONS.forEach(section => { + MODULE_ORDERING[section].forEach(category => { + category.items.forEach(moduleID => { + moduleIDToURLMap[moduleID] = `/${section}/${moduleID}`; + }) + }); +}); + +export { moduleIDToURLMap }; diff --git a/src/components/Dashboard/ActiveItems.tsx b/src/components/Dashboard/ActiveItems.tsx index e69de29..389d883 100644 --- a/src/components/Dashboard/ActiveItems.tsx +++ b/src/components/Dashboard/ActiveItems.tsx @@ -0,0 +1,89 @@ +import * as React from 'react'; +import { Link } from 'gatsby'; + +type ActiveItemStatus = 'Solving' | 'Skipped' | 'In Progress'; + +export type ActiveItem = { + label: string; + status: ActiveItemStatus; + url: string; +}; + +const statusClasses: { [key in ActiveItemStatus]: string } = { + Solving: 'bg-yellow-100 text-yellow-800', + Skipped: 'bg-gray-100 text-gray-800', + 'In Progress': 'bg-green-100 text-green-800', +}; + +export default function ActiveItems({ + type, + items, +}: { + type: 'problems' | 'modules'; + items: ActiveItem[]; +}) { + return ( +
+
+

+ Active {type === 'problems' ? 'Problems' : 'Modules'} +

+ {/*
*/} + {/*

*/} + {/* */} + {/* Intro: Input & Output*/} + {/* */} + {/* Practicing*/} + {/* */} + {/* */} + {/*

*/} + {/*

*/} + {/* */} + {/* Intro: Expected Knowledge*/} + {/* */} + {/* Skipped*/} + {/* */} + {/* */} + {/*

*/} + {/*
*/} +
+ {items.map((item, idx) => ( +

+ + {item.label} + + {item.status} + + +

+ ))} + {/*

*/} + {/* */} + {/* Longest Common Subsequence*/} + {/* */} + {/* Skipped*/} + {/* */} + {/* */} + {/*

*/} +
+
+
+ ); +} diff --git a/src/components/Dashboard/DashboardNav.tsx b/src/components/Dashboard/DashboardNav.tsx index e69de29..28e1a16 100644 --- a/src/components/Dashboard/DashboardNav.tsx +++ b/src/components/Dashboard/DashboardNav.tsx @@ -0,0 +1,213 @@ +import * as React from 'react'; +// @ts-ignore +import logo from '../../assets/logo.svg'; +// @ts-ignore +import logoSquare from '../../assets/logo-square.png'; + +export default function DashboardNav() { + return ( + + ); +} diff --git a/src/components/Dashboard/WelcomeBackBanner.tsx b/src/components/Dashboard/WelcomeBackBanner.tsx index e69de29..3061cd1 100644 --- a/src/components/Dashboard/WelcomeBackBanner.tsx +++ b/src/components/Dashboard/WelcomeBackBanner.tsx @@ -0,0 +1,43 @@ +import { Link } from 'gatsby'; +import * as React from 'react'; + +export default function WelcomeBackBanner({ + lastViewedModuleURL, + lastViewedModuleLabel, +}) { + return ( +
+ +
+

+ {lastViewedModuleURL + ? 'Welcome Back!' + : 'Welcome to the USACO Guide!'} +

+
+

+ {lastViewedModuleURL + ? `Pick up where you left off. Your last viewed module was ${lastViewedModuleLabel}.` + : `Get started on the first module, "Using This Guide."`} +

+
+
+
+ + + +
+ +
+ ); +} diff --git a/src/context/UserDataContext.tsx b/src/context/UserDataContext.tsx index cc43758..2f7f3ed 100644 --- a/src/context/UserDataContext.tsx +++ b/src/context/UserDataContext.tsx @@ -24,6 +24,9 @@ const UserDataContext = createContext<{ problem: Problem, status: ProblemProgress ) => void; + + lastViewedModule: string; + setLastViewedModule: (moduleID: string) => void; }>({ lang: 'showAll', setLang: null, @@ -31,6 +34,8 @@ const UserDataContext = createContext<{ setModuleProgress: null, userProgressOnProblems: null, setUserProgressOnProblems: null, + lastViewedModule: null, + setLastViewedModule: null, }); const langKey = 'guide:userData:lang'; @@ -70,6 +75,18 @@ const getProblemStatusFromStorage = () => { return v || {}; }; +const lastViewedModuleKey = 'guide:userData:lastViewedModule'; +const getLastViewedModuleFromStorage = () => { + let stickyValue = window.localStorage.getItem(lastViewedModuleKey); + let v = null; + try { + v = JSON.parse(stickyValue); + } catch (e) { + console.error("Couldn't parse last viewed module", e); + } + return v || null; +}; + export const UserDataProvider = ({ children }) => { const [lang, setLang] = useState('showAll'); const [userProgress, setUserProgress] = useState<{ @@ -78,44 +95,57 @@ export const UserDataProvider = ({ children }) => { const [problemStatus, setProblemStatus] = useState<{ [key: string]: ProblemProgress; }>({}); + const [lastViewedModule, setLastViewedModule] = useState(null); React.useEffect(() => { setLang(getLangFromStorage()); setUserProgress(getProgressFromStorage()); setProblemStatus(getProblemStatusFromStorage()); + setLastViewedModule(getLastViewedModuleFromStorage()); }, []); + const userData = React.useMemo( + () => ({ + lang: lang as UserLang, + setLang: lang => { + window.localStorage.setItem(langKey, JSON.stringify(lang)); + setLang(lang); + }, + userProgressOnModules: userProgress, + setModuleProgress: (moduleID: string, progress: ModuleProgress) => { + const newProgress = { + ...getProgressFromStorage(), + [moduleID]: progress, + }; + window.localStorage.setItem(progressKey, JSON.stringify(newProgress)); + setUserProgress(newProgress); + }, + userProgressOnProblems: problemStatus, + setUserProgressOnProblems: (problem, status) => { + const newStatus = { + ...getProblemStatusFromStorage(), + [problem.uniqueID]: status, + }; + window.localStorage.setItem( + problemStatusKey, + JSON.stringify(newStatus) + ); + setProblemStatus(newStatus); + }, + lastViewedModule, + setLastViewedModule: moduleID => { + window.localStorage.setItem( + lastViewedModuleKey, + JSON.stringify(moduleID) + ); + setLastViewedModule(moduleID); + }, + }), + [lang, userProgress, problemStatus, lastViewedModule] + ); + return ( - { - window.localStorage.setItem(langKey, JSON.stringify(lang)); - setLang(lang); - }, - userProgressOnModules: userProgress, - setModuleProgress: (moduleID: string, progress: ModuleProgress) => { - const newProgress = { - ...getProgressFromStorage(), - [moduleID]: progress, - }; - window.localStorage.setItem(progressKey, JSON.stringify(newProgress)); - setUserProgress(newProgress); - }, - userProgressOnProblems: problemStatus, - setUserProgressOnProblems: (problem, status) => { - const newStatus = { - ...getProblemStatusFromStorage(), - [problem.uniqueID]: status, - }; - window.localStorage.setItem( - problemStatusKey, - JSON.stringify(newStatus) - ); - setProblemStatus(newStatus); - }, - }} - > + {children} ); diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx index ca0e76e..460c303 100644 --- a/src/pages/dashboard.tsx +++ b/src/pages/dashboard.tsx @@ -1,347 +1,78 @@ import * as React from 'react'; -import { Link, PageProps } from 'gatsby'; +import { graphql, Link, PageProps } from 'gatsby'; import Layout from '../components/layout'; import SEO from '../components/seo'; import { useState } from 'react'; -// @ts-ignore -import logo from '../assets/logo.svg'; -// @ts-ignore -import logoSquare from '../assets/logo-square.png'; import SectionProgress from '../components/Dashboard/SectionProgress'; import SectionProgressBar from '../components/Dashboard/SectionProgressBar'; +import UserDataContext from '../context/UserDataContext'; +import WelcomeBackBanner from '../components/Dashboard/WelcomeBackBanner'; +import { + moduleIDToSectionMap, + moduleIDToURLMap, + SECTION_LABELS, +} from '../../content/ordering'; +import DashboardNav from '../components/Dashboard/DashboardNav'; +import ActiveItems, { ActiveItem } from '../components/Dashboard/ActiveItems'; export default function DashboardPage(props: PageProps) { const [isMobileNavOpen, setIsMobileNavOpen] = useState(false); + const { modules } = props.data as any; + const moduleIDToName = modules.edges.reduce((acc, cur) => { + acc[cur.node.frontmatter.id] = cur.node.frontmatter.title; + return acc; + }, {}); + const { + lastViewedModule: lastViewedModuleID, + userProgressOnModules, + } = React.useContext(UserDataContext); + const lastViewedModuleURL = moduleIDToURLMap[lastViewedModuleID]; + const activeModules: ActiveItem[] = React.useMemo(() => { + return Object.keys(userProgressOnModules) + .filter( + x => + userProgressOnModules[x] === 'Reading' || + userProgressOnModules[x] === 'Practicing' || + userProgressOnModules[x] === 'Skipped' + ) + .map(x => ({ + label: `${SECTION_LABELS[moduleIDToSectionMap[x]]}: ${ + moduleIDToName[x] + }`, + url: moduleIDToURLMap[x], + status: + userProgressOnModules[x] === 'Skipped' ? 'Skipped' : 'In Progress', + })); + }, [userProgressOnModules]); + const activeProblems: ActiveItem[] = []; return ( - +
- +
- {/*
*/} - {/*
*/} - {/*

*/} - {/* Welcome to the USACO Guide!*/} - {/*

*/} - {/*
*/} - {/*

*/} - {/* Get started on the first module, "Using this Guide."*/} - {/*

*/} - {/*
*/} - {/*
*/} - {/* */} - {/* Get Started! →*/} - {/* */} - {/*
*/} - {/*
*/} - {/*
*/} -
- -
-

- Welcome Back! -

-
-

- Pick up where you left off. Your last viewed module was - Input & Output. -

-
-
-
- - - -
- -
+
-
-
- + {activeProblems.length > 0 && ( +
+
-
-
-
- + )} + {activeModules.length > 0 && ( +
+
-
+ )}
@@ -460,3 +191,18 @@ export default function DashboardPage(props: PageProps) { ); } + +export const pageQuery = graphql` + query { + modules: allMdx { + edges { + node { + frontmatter { + title + id + } + } + } + } + } +`; diff --git a/src/templates/moduleTemplate.tsx b/src/templates/moduleTemplate.tsx index c72ad71..5cb061e 100644 --- a/src/templates/moduleTemplate.tsx +++ b/src/templates/moduleTemplate.tsx @@ -7,11 +7,17 @@ import { SECTION_LABELS } from '../../content/ordering'; import { graphqlToModuleInfo } from '../utils'; import SEO from '../components/seo'; import ModuleLayout from '../components/ModuleLayout/ModuleLayout'; +import { useContext } from 'react'; +import UserDataContext from '../context/UserDataContext'; export default function Template(props) { const { mdx } = props.data; // data.markdownRemark holds your post data const { body } = mdx; const module = React.useMemo(() => graphqlToModuleInfo(mdx), [mdx]); + const { setLastViewedModule } = useContext(UserDataContext); + React.useEffect(() => { + setLastViewedModule(module.id); + }, []); return ( Date: Sun, 19 Jul 2020 13:49:54 -0400 Subject: [PATCH 3/8] create separate lambda module --- content/1_Intro/Lambda.mdx | 89 +++++++++++++++++++++++++++++ content/1_Intro/Tips.mdx | 80 +------------------------- content/2_Bronze/Unordered.mdx | 14 +++-- content/3_Silver/Custom_Cpp_STL.mdx | 39 +++++-------- content/3_Silver/Harder_Ordered.mdx | 1 - content/3_Silver/Intro_Ordered.mdx | 59 ++++++++++++++++--- content/3_Silver/Sorting_Custom.mdx | 3 +- content/3_Silver/Stacks_Queues.mdx | 47 --------------- content/4_Gold/SP.mdx | 2 +- content/ordering.ts | 1 + 10 files changed, 168 insertions(+), 167 deletions(-) create mode 100644 content/1_Intro/Lambda.mdx diff --git a/content/1_Intro/Lambda.mdx b/content/1_Intro/Lambda.mdx new file mode 100644 index 0000000..e8ef592 --- /dev/null +++ b/content/1_Intro/Lambda.mdx @@ -0,0 +1,89 @@ +--- +id: lambda +title: Lambda Functions in C++ +author: Benjamin Qi +description: "?" +--- + +## Introduction + + + + {' '} + + + + + reference + + +(describe more) + +oops sort of confusing + +## Recursive Lambdas + + + + + + +We can do stuff like the following in C++14: + +```cpp +namespace std { + +template +class y_combinator_result { + Fun fun_; +public: + template + explicit y_combinator_result(T &&fun): fun_(std::forward(fun)) {} + + template + decltype(auto) operator()(Args &&...args) { + return fun_(std::ref(*this), std::forward(args)...); + } +}; + +template +decltype(auto) y_combinator(Fun &&fun) { + return y_combinator_result>(std::forward(fun)); +} + +} // namespace std + +int main() { + cout << y_combinator([](auto gcd, int a, int b) -> int { + return b == 0 ? a : gcd(b, a % b); + })(20,30) << "\n"; // outputs 10 +} +``` + +Looks like [ecnerwal](https://codeforces.com/contest/1375/submission/86008510) uses these a lot ... + + + \ No newline at end of file diff --git a/content/1_Intro/Tips.mdx b/content/1_Intro/Tips.mdx index ef03a84..cf7ed6c 100644 --- a/content/1_Intro/Tips.mdx +++ b/content/1_Intro/Tips.mdx @@ -116,82 +116,4 @@ Instructions (Mac): ``` 4. Run `makeSnip` from terminal. It should display a list of the templates that will be added as snippets. - 5. If this succeeded, then typing `Temp` in a cpp file will automatically load my template! - - -## Lambda Expressions - - - - {' '} - - - -(describe more) - -### Recursive Lambdas - - - - - - -We can do stuff like the following in C++14: - -```cpp -namespace std { - -template -class y_combinator_result { - Fun fun_; -public: - template - explicit y_combinator_result(T &&fun): fun_(std::forward(fun)) {} - - template - decltype(auto) operator()(Args &&...args) { - return fun_(std::ref(*this), std::forward(args)...); - } -}; - -template -decltype(auto) y_combinator(Fun &&fun) { - return y_combinator_result>(std::forward(fun)); -} - -} // namespace std - -int main() { - cout << y_combinator([](auto gcd, int a, int b) -> int { - return b == 0 ? a : gcd(b, a % b); - })(20,30) << "\n"; // outputs 10 -} -``` - -Looks like [ecnerwal](https://codeforces.com/contest/1375/submission/86008510) uses these a lot ... - - - \ No newline at end of file + 5. If this succeeded, then typing `Temp` in a cpp file will automatically load my template! \ No newline at end of file diff --git a/content/2_Bronze/Unordered.mdx b/content/2_Bronze/Unordered.mdx index c56c0d6..b440e74 100644 --- a/content/2_Bronze/Unordered.mdx +++ b/content/2_Bronze/Unordered.mdx @@ -149,6 +149,8 @@ System.out.println(map.containsKey(1)); // true ### Custom Hashing +There is no built in method for hashing pairs or vectors. Namely, `unordered_set>` does not work. In this case, we can use an [ordered map](../silver/intro-ordered) (which supports all of the functions used in the code above) or declare our own hash function. + @@ -197,7 +199,7 @@ int main() { } ``` -However, this hash function is quite bad; if we insert $(0,0), (1,1), (2,2) \ldots$ then they will all be mapped to the same bucket. +However, this hash function is quite bad; if we insert $(0,0), (1,1), (2,2) \ldots$ then they will all be mapped to the same bucket (so it would easily be **hacked**). @@ -232,9 +234,11 @@ Essentially use `unordered_map` defined in the blog above ```cpp struct chash { /// use most bits rather than just the lowest ones const uint64_t C = ll(2e18*PI)+71; // large odd number - const int RANDOM = rng(); - ll operator()(ll x) const { /// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html - return __builtin_bswap64((x^RANDOM)*C); } + const int RANDOM = rng(); // random 32-bit number + ll operator()(ll x) const { + // https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html + return __builtin_bswap64((x^RANDOM)*C); + } }; template using um = unordered_map; ``` @@ -247,7 +251,7 @@ template using um = unordered_map; ### `gp_hash_table` -Mentioned in several of the links above. See Gold for dtails. +Mentioned in several of the links above. See [Gold](../gold/faster-hashmap) for details. ## Problems diff --git a/content/3_Silver/Custom_Cpp_STL.mdx b/content/3_Silver/Custom_Cpp_STL.mdx index c6498e9..debb4ce 100644 --- a/content/3_Silver/Custom_Cpp_STL.mdx +++ b/content/3_Silver/Custom_Cpp_STL.mdx @@ -5,12 +5,14 @@ author: Siyong Huang, Benjamin Qi prerequisites: - sorting-custom - intro-ordered + - lambda description: "More ways to write custom comparators in C++ and incorporating them into STL objects." frequency: 1 --- Covers all of this material. + reference
@@ -45,6 +47,12 @@ int main() { ## Comparator + + + + +### With a Function + ```cpp #include using namespace std; @@ -66,20 +74,14 @@ int main() { } ``` - +You can also use the following syntax to declare set `v` using a function: -You can also use the following syntax to declare set `v` using a function +`set v(cmp);` -`set v(cmp);` - - - -Lambda expressions also work: +### With Lambda Expressions ```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; @@ -92,13 +94,11 @@ int main() { } ``` - - -You can also use the following syntax to declare set `v` using a lambda +You can also use the following syntax to declare set `v` using a lambda: `set v(cmp);` - +though `decltype(cmp)` is **not** actually equivalent to `bool(*)(const Edge&,const Edge&)`. ## Functors @@ -191,15 +191,4 @@ map> b; priority_queue,greater> c; ``` - - -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. - - +Using a custom comparator for priority queues is especially common. Again, a C++ priority queue will pop its largest element by default, while the above code will cause one to pop its smallest element instead. \ No newline at end of file diff --git a/content/3_Silver/Harder_Ordered.mdx b/content/3_Silver/Harder_Ordered.mdx index a856d78..18c548f 100644 --- a/content/3_Silver/Harder_Ordered.mdx +++ b/content/3_Silver/Harder_Ordered.mdx @@ -4,7 +4,6 @@ title: "Harder Problems with Ordered Sets" author: Benjamin Qi prerequisites: - custom-cpp-stl - - stacks-queues description: "More advanced uses of ordered sets with example problems." frequency: 2 --- diff --git a/content/3_Silver/Intro_Ordered.mdx b/content/3_Silver/Intro_Ordered.mdx index 7e60a9a..1b8e61c 100644 --- a/content/3_Silver/Intro_Ordered.mdx +++ b/content/3_Silver/Intro_Ordered.mdx @@ -3,7 +3,7 @@ id: intro-ordered title: "Introduction to Ordered Sets" author: Darren Yao, Benjamin Qi prerequisites: - - Bronze - Unordered Maps & Sets + - unordered description: "A data structure that supports quick insertion and deletion by maintaining keys in sorted order." frequency: 2 --- @@ -129,7 +129,7 @@ System.out.println(map.lowerKey(3)); // ERROR ## Multisets -Lastly, there is the **multiset**, which is essentially a sorted set that allows multiple copies of the same element. +A **multiset** is a sorted set that allows multiple copies of the same element. @@ -189,6 +189,54 @@ static void remove(int x){ +## Priority Queues + +A **priority queue** supports the following operations: insertion of elements, deletion of the element considered highest priority, and retrieval of the highest priority element, all in $O(\log N)$ time according to the number of elements in the priority queue. Like sets, priority is based on a **comparator function**. + +Of course, all of these functions are supported by multisets, but priority queues are simpler (so they are much faster). + + + + + +### [C++](http://www.cplusplus.com/reference/queue/priority_queue/) + +```cpp +priority_queue pq; +pq.push(7); // [7] +pq.push(2); // [2, 7] +pq.push(1); // [1, 2, 7] +pq.push(5); // [1, 2, 5, 7] +cout << pq.top() << endl; // 7 +pq.pop(); // [1, 2, 5] +pq.pop(); // [1, 2] +pq.push(6); // [1, 2, 6] +``` + + + + + +### Java + +In Java, we delete and retrieve the element of **lowest** rather than highest priority. + +```java +PriorityQueue pq = new PriorityQueue(); +pq.add(7); // [7] +pq.add(2); // [7, 2] +pq.add(1); // [7, 2, 1] +pq.add(5); // [7, 5, 2, 1] +System.out.println(pq.peek()); // 1 +pq.poll(); // [7, 5, 2] +pq.poll(); // [7, 5] +pq.add(6); // [7, 6, 5] +``` + + + + + ## Using Iterators @@ -198,14 +246,9 @@ static void remove(int x){ next(), prev(), ++, -- + - - - - - -
diff --git a/content/3_Silver/Sorting_Custom.mdx b/content/3_Silver/Sorting_Custom.mdx index d3d5899..51d69b1 100644 --- a/content/3_Silver/Sorting_Custom.mdx +++ b/content/3_Silver/Sorting_Custom.mdx @@ -5,6 +5,7 @@ frequency: 3 author: Darren Yao, Siyong Huang, Michael Cao, Benjamin Qi prerequisites: - pairs-tuples + - lambda description: "Both Java and C++ have built-in functions for sorting. However, if we use custom objects, or if we want to sort elements in a different order, then we'll need to use a custom comparator." --- @@ -279,7 +280,7 @@ int main() { ``` -We can also use [lambda expressions](https://www.geeksforgeeks.org/lambda-expression-in-c/) in C++11 or above. +We can also use lambda expressions in C++11 or above: ```cpp sort(begin(v),end(v),[](const Edge& x, const Edge& y) { return x.w < y.w; }); diff --git a/content/3_Silver/Stacks_Queues.mdx b/content/3_Silver/Stacks_Queues.mdx index 084d39c..fb38882 100644 --- a/content/3_Silver/Stacks_Queues.mdx +++ b/content/3_Silver/Stacks_Queues.mdx @@ -173,53 +173,6 @@ deque.removeLast(); // [1, 3] -## Priority Queues - - - - - -### [C++](http://www.cplusplus.com/reference/queue/priority_queue/) - -A priority queue supports the following operations: insertion of elements, deletion of the element considered highest priority, and retrieval of the highest priority element, all in $O(\log n)$ time according to the number of elements in the priority queue. Priority is based on a comparator function. The priority queue is one of the most important data structures in competitive programming, so make sure you understand how and when to use it. - -```cpp -priority_queue pq; -pq.push(7); // [7] -pq.push(2); // [2, 7] -pq.push(1); // [1, 2, 7] -pq.push(5); // [1, 2, 5, 7] -cout << pq.top() << endl; // 7 -pq.pop(); // [1, 2, 5] -pq.pop(); // [1, 2] -pq.push(6); // [1, 2, 6] -``` - - - - - - -### Java - -In Java, we delete and retrieve the element of **lowest** priority. - -```java -PriorityQueue pq = new PriorityQueue(); -pq.add(7); // [7] -pq.add(2); // [7, 2] -pq.add(1); // [7, 2, 1] -pq.add(5); // [7, 5, 2, 1] -System.out.println(pq.peek()); // 1 -pq.poll(); // [7, 5, 2] -pq.poll(); // [7, 5] -pq.add(6); // [7, 6, 5] -``` - - - - - ## Monotonic Stack diff --git a/content/4_Gold/SP.mdx b/content/4_Gold/SP.mdx index 1d3d014..30abac3 100644 --- a/content/4_Gold/SP.mdx +++ b/content/4_Gold/SP.mdx @@ -4,7 +4,7 @@ title: "Shortest Paths with Non-Negative Edge Weights" author: Benjamin Qi prerequisites: - bfs - - stacks-queues + - intro-ordered description: "Introduces Dijkstra's Algorithm for a single source shortest path as well as Floyd-Warshall for All-Pairs Shortest Path." frequency: 3 --- diff --git a/content/ordering.ts b/content/ordering.ts index 9aa1212..f12b5d6 100644 --- a/content/ordering.ts +++ b/content/ordering.ts @@ -45,6 +45,7 @@ const MODULE_ORDERING: {[key in SectionID]: Category[]} = { "fast-io", "debugging", "cpp-tips", + "lambda", ] }, { From 1a9151ec64675085c1a7fab3c0b1bca7a7069589 Mon Sep 17 00:00:00 2001 From: Nathan Wang Date: Sun, 19 Jul 2020 12:12:40 -0700 Subject: [PATCH 4/8] add functionality to dashboard; refactor problems --- content/1_Intro/Expected.mdx | 6 +- content/1_Intro/Input_Output.mdx | 14 +-- content/2_Bronze/Complete_Search.mdx | 8 +- content/2_Bronze/Gen_Perm.mdx | 10 +- content/2_Bronze/Intro_DS.mdx | 8 +- content/2_Bronze/Intro_Graphs.mdx | 6 +- content/2_Bronze/Intro_Greedy.mdx | 8 +- content/2_Bronze/Rect_Geo.mdx | 24 ++-- content/2_Bronze/Simulation.mdx | 8 +- content/2_Bronze/Unordered.mdx | 10 +- content/3_Silver/Binary_Search_Ans.mdx | 10 +- content/3_Silver/Binary_Search_Sorted.mdx | 6 +- content/3_Silver/DFS.mdx | 14 +-- content/3_Silver/Flood_Fill.mdx | 8 +- content/3_Silver/Func_Graphs.mdx | 8 +- content/3_Silver/Greedy.mdx | 12 +- content/3_Silver/Harder_Ordered.mdx | 8 +- content/3_Silver/Intro_Ordered.mdx | 6 +- content/3_Silver/Prefix_Sums.mdx | 18 ++- content/3_Silver/Sliding.mdx | 12 +- content/3_Silver/Sorting_2_Old.mdx | 2 +- content/3_Silver/Sorting_Custom.mdx | 8 +- content/3_Silver/Sorting_Methods.mdx | 6 +- content/3_Silver/Sorting_Old.mdx | 6 +- content/3_Silver/Stacks_Queues.mdx | 8 +- content/4_Gold/BFS.mdx | 10 +- content/4_Gold/Cyc.mdx | 10 +- content/4_Gold/DP.mdx | 14 +-- content/4_Gold/DP_Trees.mdx | 11 +- content/4_Gold/DSU.mdx | 8 +- content/4_Gold/Faster_Hash.mdx | 6 +- content/4_Gold/Intro_NT.mdx | 8 +- content/4_Gold/MST.mdx | 8 +- content/4_Gold/PURS.mdx | 13 +- content/4_Gold/SP.mdx | 12 +- content/4_Gold/SRQ.mdx | 12 +- content/4_Gold/Springboards.mdx | 8 +- content/4_Gold/String_Hashing.mdx | 10 +- content/4_Gold/TopoSort.mdx | 10 +- content/4_Gold/Tree_Euler.mdx | 10 +- content/5_Plat/2DRQ.mdx | 14 +-- content/5_Plat/BCC_2CC.mdx | 15 +-- content/5_Plat/Bin_Jump.mdx | 10 +- content/5_Plat/Bitsets.mdx | 14 +-- content/5_Plat/Centroid.mdx | 6 +- content/5_Plat/Convex_Hull.mdx | 14 +-- content/5_Plat/DP_Bitmasks.mdx | 8 +- content/5_Plat/DP_Ranges.mdx | 6 +- content/5_Plat/Eulerian_Tours.mdx | 8 +- content/5_Plat/Eulers_Formula.mdx | 10 +- content/5_Plat/Flows.mdx | 16 ++- content/5_Plat/Fracture.mdx | 8 +- content/5_Plat/Geo_Pri.mdx | 8 +- content/5_Plat/HLD.mdx | 8 +- content/5_Plat/LC.mdx | 10 +- content/5_Plat/Lagrange.mdx | 8 +- content/5_Plat/Merging.mdx | 8 +- content/5_Plat/Offline_Con.mdx | 8 +- content/5_Plat/RURQ.mdx | 14 +-- content/5_Plat/SCC.mdx | 10 +- content/5_Plat/SPneg.mdx | 10 +- content/5_Plat/Seg_Ext.mdx | 16 ++- content/5_Plat/Slope.mdx | 14 +-- content/5_Plat/Sqrt.mdx | 10 +- content/5_Plat/String_Search.mdx | 16 ++- content/5_Plat/Suffix_Array.mdx | 14 +-- content/5_Plat/Sweep_Line.mdx | 12 +- content/6_Advanced/Extend_Euclid.mdx | 8 +- content/6_Advanced/FFT-ext.mdx | 8 +- content/6_Advanced/Flow_LB.mdx | 8 +- content/6_Advanced/LCT.mdx | 12 +- content/6_Advanced/Segtree_Beats.mdx | 6 +- content/6_Advanced/String_Suffix.mdx | 8 +- content/6_Advanced/Treaps.mdx | 6 +- docs/Content Documentation.md | 56 ++++----- gatsby-node.ts | 44 ++++++- package.json | 1 + src/components/Dashboard/ActiveItems.tsx | 24 ---- src/components/ModuleLayout/ModuleLayout.tsx | 2 +- .../markdown/ProblemsList/ProblemsList.tsx | 11 +- src/pages/dashboard.tsx | 31 ++++- yarn.lock | 118 +++++++++++++++++- 82 files changed, 515 insertions(+), 507 deletions(-) diff --git a/content/1_Intro/Expected.mdx b/content/1_Intro/Expected.mdx index b3b50f6..25ae612 100644 --- a/content/1_Intro/Expected.mdx +++ b/content/1_Intro/Expected.mdx @@ -9,15 +9,13 @@ prerequisites: import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { general: [ new Problem("Bronze", "Promotion Counting", "591", "Very Easy"), new Problem("Bronze", "Word Processor", "987", "Very Easy"), new Problem("Bronze", "Square Pasture", "663", "Very Easy"), new Problem("Bronze", "Bucket Brigade", "939", "Very Easy"), ] - } }; The remainder of this guide assumes that you know the basics of how to code in one of the languages listed above, including the following topics: @@ -52,7 +50,7 @@ You may find the following resources helpful for familiarizing yourself with you The following require relatively little programming experience and no algorithmic knowledge. - + 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. diff --git a/content/1_Intro/Input_Output.mdx b/content/1_Intro/Input_Output.mdx index dfe2d8f..e382d5f 100644 --- a/content/1_Intro/Input_Output.mdx +++ b/content/1_Intro/Input_Output.mdx @@ -9,21 +9,13 @@ prerequisites: import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { cses: [ new Problem("CSES", "Weird Algorithm", "1068", "Very Easy"), ], fence: [ new Problem("Bronze", "Fence Painting", "567", "Very Easy"), ], - general: [ - new Problem("Bronze", "Promotion Counting", "591", "Very Easy"), - new Problem("Bronze", "Word Processor", "987", "Very Easy"), - new Problem("Bronze", "Square Pasture", "663", "Very Easy"), - new Problem("Bronze", "Bucket Brigade", "939", "Very Easy"), - ] - } }; @@ -38,7 +30,7 @@ export const metadata = { In most websites (such as CodeForces and CSES), input and output are **standard**. - + Note that this problem requires **64-bit integers**. @@ -170,7 +162,7 @@ public static void main(String[] args) { ## File I/O - + 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`. diff --git a/content/2_Bronze/Complete_Search.mdx b/content/2_Bronze/Complete_Search.mdx index 90dbe16..2b98190 100644 --- a/content/2_Bronze/Complete_Search.mdx +++ b/content/2_Bronze/Complete_Search.mdx @@ -8,8 +8,7 @@ frequency: 4 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { easier: [ new Problem("CSES", "Apple Division", "1623", "Intro|Very Easy", false, ["Recursion"], "all $2^n$ subsets"), new Problem("Bronze", "Diamond Collector", "639", "Easy", false, ["Nested Loop"], "fix the min"), // 99.9 @@ -30,7 +29,6 @@ export const metadata = { new Problem("Bronze", "Bull in a China Shop", "640", "Very Hard", false, [], "lots of WA on this one"), // 47.38 new Problem("Silver", "Field Reduction", "642", "Very Hard", false, [], ""), ], - } }; @@ -115,8 +113,8 @@ A couple notes: ### Easier - + ### Harder - + diff --git a/content/2_Bronze/Gen_Perm.mdx b/content/2_Bronze/Gen_Perm.mdx index 20d5951..5c1d53e 100644 --- a/content/2_Bronze/Gen_Perm.mdx +++ b/content/2_Bronze/Gen_Perm.mdx @@ -10,8 +10,7 @@ prerequisites: import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { permSam: [ new Problem("CSES", "Creating Strings I", "1622", "Intro|Easy", false, [], "all perms of string"), ], @@ -22,10 +21,9 @@ export const metadata = { new Problem("CSES", "Chessboard and Queens", "1624", "Normal", false, [], "Recursively backtrack. See CSES book for more details."), new Problem("Bronze", "Livestock Lineup", "965", "Hard", false, ["permutations"], ""), // 91.95 ] - } }; - +
@@ -39,7 +37,7 @@ A **permutation** is a reordering of a list of elements. Some problems will ask This term is mentioned quite frequently: - + Think about how are words ordered in a dictionary. (In fact, this is where the term "lexicographical" comes from.) @@ -125,4 +123,4 @@ public class Test { ### Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/2_Bronze/Intro_DS.mdx b/content/2_Bronze/Intro_DS.mdx index 3203918..39e0fd1 100644 --- a/content/2_Bronze/Intro_DS.mdx +++ b/content/2_Bronze/Intro_DS.mdx @@ -8,8 +8,7 @@ frequency: 4 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { bubble: [ new Problem("HR", "Bubble Sort", "https://www.hackerrank.com/challenges/ctci-bubble-sort/problem", "Easy", false, [], "O(N^2)"), ], @@ -18,7 +17,6 @@ export const metadata = { new Problem("CSES", "Stick Lengths", "1074", "Normal", false, [], "Spoiler: Optimal length is median"), new Problem("Silver", "Teleportation", "812", "Very Hard", false, [], ""), ], - } }; @@ -279,7 +277,7 @@ for(auto element : v) { ## Sorting - + **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. @@ -322,4 +320,4 @@ Two ways to avoid this: ## Problems - + diff --git a/content/2_Bronze/Intro_Graphs.mdx b/content/2_Bronze/Intro_Graphs.mdx index ddd1d70..23d2387 100644 --- a/content/2_Bronze/Intro_Graphs.mdx +++ b/content/2_Bronze/Intro_Graphs.mdx @@ -8,8 +8,7 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { general: [ new Problem("Silver", "Grass Planting", "894", "Normal", false, ["tree"]), new Problem("Bronze", "The Great Revegetation", "916", "Hard", false, []), @@ -19,7 +18,6 @@ export const metadata = { new Problem("Bronze", "Swapity Swap", "1013", "Hard", false, ["permutation"], "Hint: One option is to keep swapping until the permutation returns to its original state (but can you do better?)."), new Problem("Bronze", "Cow Evolution", "941", "Hard", false, [], ""), ] - } }; Graphs can be used to represent many things, from images to wireless signals, but one of the simplest analogies is to a map. Consider a map with several cities and bidirectional roads connecting the cities. Some problems relating to graphs are: @@ -45,4 +43,4 @@ Both of these tasks will be covered in higher divisions. For now, it suffices to ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/2_Bronze/Intro_Greedy.mdx b/content/2_Bronze/Intro_Greedy.mdx index 1e2ef55..35c200f 100644 --- a/content/2_Bronze/Intro_Greedy.mdx +++ b/content/2_Bronze/Intro_Greedy.mdx @@ -8,8 +8,7 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { tutorial: [ new Problem("Bronze", "Mad Scientist", "1012", "Normal", false, [], ""), ], @@ -17,7 +16,6 @@ export const metadata = { 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 @@ -141,7 +139,7 @@ If we use greedy based on highest value first, we choose item A and then we are Try to come up with a greedy algorithm for the USACO Bronze problem "Mad Scientist." - + @@ -165,7 +163,7 @@ Sometimes, if the algorithm is easy enough to implement, you don't even need to ## Problems - + diff --git a/content/2_Bronze/Rect_Geo.mdx b/content/2_Bronze/Rect_Geo.mdx index f697e5d..ca83c39 100644 --- a/content/2_Bronze/Rect_Geo.mdx +++ b/content/2_Bronze/Rect_Geo.mdx @@ -7,17 +7,15 @@ frequency: 2 --- import { Problem } from "../models"; -export const metadata = { - problems: { - blocked: [ - new Problem("Bronze", "Blocked Billboard", "759", "Easy", false, ["rect"]), - ], - general: [ - new Problem("Bronze", "Square Pasture", "663", "Very Easy", false, ["rect"]), - new Problem("Bronze", "Blocked Billboard II", "783", "Easy", false, ["rect"]), - new Problem("CF", "Div. 3 C - White Sheet", "contest/1216/problem/C", "Normal", false, ["rect"],"See this code (TODO; codeforces is down) for a nice implementation using the Java Rectangle class."), - ] - } +export const problems = { + blocked: [ + new Problem("Bronze", "Blocked Billboard", "759", "Easy", false, ["rect"]), + ], + general: [ + new Problem("Bronze", "Square Pasture", "663", "Very Easy", false, ["rect"]), + new Problem("Bronze", "Blocked Billboard II", "783", "Easy", false, ["rect"]), + new Problem("CF", "Div. 3 C - White Sheet", "contest/1216/problem/C", "Normal", false, ["rect"],"See this code (TODO; codeforces is down) for a nice implementation using the Java Rectangle class."), + ] }; @@ -30,7 +28,7 @@ Most only include two or three squares or rectangles, in which case you can simp ## Example: Blocked Billboard - + ### Naive Solution @@ -212,4 +210,4 @@ int main(){ ## Problems - + diff --git a/content/2_Bronze/Simulation.mdx b/content/2_Bronze/Simulation.mdx index 3e6cc94..9f51e74 100644 --- a/content/2_Bronze/Simulation.mdx +++ b/content/2_Bronze/Simulation.mdx @@ -8,8 +8,7 @@ frequency: 4 import { Problem } from "../models" -export const metadata = { - problems: { +export const problems = { easier: [ new Problem("Bronze", "Shell Game", "891", "Easy", false, ["Nested Loop"]), // 99.93 new Problem("Bronze", "Mixing Milk", "855", "Easy", false, ["Single Loop"], "just pour 100 times"), // 99.87 @@ -26,7 +25,6 @@ export const metadata = { new Problem("Bronze", "Milk Measurement", "761", "Hard"), // 95.97 new Problem("Bronze", "Angry Cows", "592", "Hard", false, [], ""), // 94.15 ] - } }; @@ -186,8 +184,8 @@ pw.close(); // flush the output ### Easier - + ### Harder - + diff --git a/content/2_Bronze/Unordered.mdx b/content/2_Bronze/Unordered.mdx index c56c0d6..852992f 100644 --- a/content/2_Bronze/Unordered.mdx +++ b/content/2_Bronze/Unordered.mdx @@ -10,8 +10,7 @@ prerequisites: import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { dis: [ new Problem("CSES", "Distinct Numbers", "1621", "Easy", false, [], "Store every number in a set and print the size."), ], @@ -23,7 +22,6 @@ export const metadata = { new Problem("Bronze", "Where Am I?", "964", "Easy", false, [], "Store all substrings in a map of , and then find the longest length such that no substring of that length appears twice."), new Problem("Silver", "Cities & States", "667", "Hard", false, [], "Store two maps of counts for the first two letters of a city and state code, then iterate over the cities and use the maps to efficently query for the corresponding counts."), ], - } }; @@ -46,7 +44,7 @@ Both Java and C++ contain two versions of sets and maps; one in which the keys a ## Sets - + @@ -105,7 +103,7 @@ for(int element : set){ ## Maps - + @@ -251,4 +249,4 @@ Mentioned in several of the links above. See Gold for dtails. ## Problems - + diff --git a/content/3_Silver/Binary_Search_Ans.mdx b/content/3_Silver/Binary_Search_Ans.mdx index cf45396..b6dc707 100644 --- a/content/3_Silver/Binary_Search_Ans.mdx +++ b/content/3_Silver/Binary_Search_Ans.mdx @@ -10,8 +10,7 @@ frequency: 3 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { ex: [ new Problem("CF", "Div 2 C - Maximum Median", "contest/1201/problem/C", "Easy", false, [], ""), ], @@ -35,7 +34,6 @@ export const metadata = { new Problem("CF", "Level Generation", "problemset/problem/818/F", "Hard", false, [], "first find out which is the best way to construct the graph, then it's possible to see that the number of edges increase for some range and then decrease; so, using binary search find the last i such that f(i-1)<=f(i)"), new Problem("CF", "Packmen", "contest/847/problem/E", "Hard", false, [], "binary search on time and check if packmen can eat all keeping left and right endpoints"), ], - } }; @@ -154,7 +152,7 @@ static long search(){ ## Example: Maximum Median - + **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. @@ -261,8 +259,8 @@ static boolean check(long x){ ## USACO Problems - + ## General Problems - + diff --git a/content/3_Silver/Binary_Search_Sorted.mdx b/content/3_Silver/Binary_Search_Sorted.mdx index ee1a896..49099d0 100644 --- a/content/3_Silver/Binary_Search_Sorted.mdx +++ b/content/3_Silver/Binary_Search_Sorted.mdx @@ -10,8 +10,7 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { bubble: [ new Problem("HR", "Bubble Sort", "https://www.hackerrank.com/challenges/ctci-bubble-sort/problem", "Easy", false, [], "O(N^2)"), new Problem("Silver", "Out of Sorts", "834", "Very Hard", false, []), @@ -19,7 +18,6 @@ export const metadata = { count: [ new Problem("Silver", "Counting Haybales", "666", "Normal", false, []), ], - } }; 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. @@ -60,7 +58,7 @@ 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. - + > 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. diff --git a/content/3_Silver/DFS.mdx b/content/3_Silver/DFS.mdx index acdd898..b7ea566 100644 --- a/content/3_Silver/DFS.mdx +++ b/content/3_Silver/DFS.mdx @@ -10,8 +10,7 @@ frequency: 4 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("CSES", "Building Roads", "1666", "Intro|Easy", false, ["DFS"]), ], @@ -49,7 +48,6 @@ export const metadata = { new Problem("Silver", "The Great Revegetation", "920", "Easy", false, ["Bipartite"]), new Problem("Silver", "Clock Tree", "1016", "Hard", false, []), ], - } }; ## Resources @@ -66,7 +64,7 @@ export const metadata = { ## Counting Connected Components - + ### Implementation @@ -128,7 +126,7 @@ public static int count_components() ### Problems - + ## Tree Problems @@ -192,14 +190,14 @@ public static void dfs(int node) ### Problems - + ## 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. - + ### Resources @@ -268,4 +266,4 @@ public static void dfs(int node) ### Problems - + diff --git a/content/3_Silver/Flood_Fill.mdx b/content/3_Silver/Flood_Fill.mdx index a7c61e7..8d89ee3 100644 --- a/content/3_Silver/Flood_Fill.mdx +++ b/content/3_Silver/Flood_Fill.mdx @@ -10,8 +10,7 @@ frequency: 3 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("LC", "Flood Fill", "https://leetcode.com/problems/flood-fill/", "Intro|Easy", false, []), new Problem("CSES", "Counting Rooms", "1192", "Easy", false, []), @@ -29,10 +28,9 @@ export const metadata = { new Problem("Silver", "Snow Boots", "811", "Hard", false, []), new Problem("Silver", "Mooyo Mooyo", "860", "Hard", false, []), ], - } }; - +
@@ -208,4 +206,4 @@ static void floodfill(int r, int c, int color){ ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/3_Silver/Func_Graphs.mdx b/content/3_Silver/Func_Graphs.mdx index 91e4e3d..7570f2d 100644 --- a/content/3_Silver/Func_Graphs.mdx +++ b/content/3_Silver/Func_Graphs.mdx @@ -11,8 +11,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("CF", "Div 2 B - Badge", "contest/1020/problem/B", "Very Easy", false, ["Func Graph"], "Try to solve the problem in $O(N)$!"), ], @@ -26,14 +25,13 @@ export const metadata = { 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/> @@ -122,4 +120,4 @@ pair detect_cycle(int *next, int start_node) //return pair(length of c ### Problems - + diff --git a/content/3_Silver/Greedy.mdx b/content/3_Silver/Greedy.mdx index 3bd67bd..5c9987c 100644 --- a/content/3_Silver/Greedy.mdx +++ b/content/3_Silver/Greedy.mdx @@ -12,8 +12,7 @@ frequency: 3 import {Problem} from "../models" -export const metadata = { - problems: { +export const problems = { movie: [ new Problem("CSES", "Movie Festival", "1629", "Easy", false, [], ""), ], @@ -42,7 +41,6 @@ export const metadata = { new Problem("CF", "Kayaking", "contest/863/problem/B", "?", false, [], "Huffman Coding?"), new Problem("CF", "New Year and Three Musketeers", "contest/611/problem/E", "Hard", false, [], "needs maps"), ] - } }; @@ -64,7 +62,7 @@ Here, we'll focus on problems where some sorting step is involved. ## Example: The Scheduling Problem - + 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? @@ -177,12 +175,12 @@ pw.close(); ## CSES Problems - + ## USACO Problems - + ## Other Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/3_Silver/Harder_Ordered.mdx b/content/3_Silver/Harder_Ordered.mdx index a856d78..332908f 100644 --- a/content/3_Silver/Harder_Ordered.mdx +++ b/content/3_Silver/Harder_Ordered.mdx @@ -11,8 +11,7 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("CSES", "Bit Inversions", "1188", "Normal", false, []), ], @@ -24,13 +23,12 @@ export const metadata = { new Problem("CF", "Mahmoud & Ehab & Function", "contest/862/problem/E", "Hard", false, [], "Hard, do not attempt until Gold/Plat (2100 on CF)"), new Problem("CF", "Tournament", "contest/878/problem/C", "Very Hard", false, [], "First solve problem for $n$-th tournament only. Extremely hard, do not attempt (2700 on CF)"), ] - } }; ## Example: Using Iterators - + @@ -129,4 +127,4 @@ int main() { ## Problems - + diff --git a/content/3_Silver/Intro_Ordered.mdx b/content/3_Silver/Intro_Ordered.mdx index 7e60a9a..387950b 100644 --- a/content/3_Silver/Intro_Ordered.mdx +++ b/content/3_Silver/Intro_Ordered.mdx @@ -10,13 +10,11 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { standard: [ new Problem("CSES", "Concert Tickets", "1091", "Easy", false, ["iterators"], "just do upper_bound"), new Problem("CSES", "Traffic Lights", "1163", "Normal", false, ["set"], "just insert into set one at a time"), ], - } }; @@ -212,4 +210,4 @@ next(), prev(), ++, -- ## Standard - \ No newline at end of file + \ No newline at end of file diff --git a/content/3_Silver/Prefix_Sums.mdx b/content/3_Silver/Prefix_Sums.mdx index cce5c29..feb8a9b 100644 --- a/content/3_Silver/Prefix_Sums.mdx +++ b/content/3_Silver/Prefix_Sums.mdx @@ -10,8 +10,7 @@ frequency: 3 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("YS", "Static Range Sum", "static_range_sum", "Easy", false, [], "equivalent to [CSES Range Sum Queries I](https://cses.fi/problemset/task/1646)"), ], @@ -47,7 +46,6 @@ export const metadata = { new Problem("Google KickStart", "Candies (Test Set 1)", "https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ff43/0000000000337b4d", "Easy", false, ["Prefix Sums"], ""), new Problem("AC", "Multiple of 2019", "https://atcoder.jp/contests/abc164/tasks/abc164_d", "Hard", false, ["Prefix Sums"], "Make use of the fact that adding 0's to the end of a number does not affect whether it is a multiple of 2019 (because 10 and 2019 are coprime)."), ], - } }; @@ -59,7 +57,7 @@ export const metadata = { ## Introduction - + Let's say we have a one-indexed integer array $\texttt{arr}$ of size $N$ and we want to compute the value of $$ @@ -206,13 +204,13 @@ These are also known as [partial sums](https://mathworld.wolfram.com/PartialSum. ### Problems - + ## Max Subarray Sum Now we'll look at some extensions. - + 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. @@ -226,11 +224,11 @@ Consider the desired maximum subarray. As you go along from left to right, the p 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. - + ## 2D Prefix Sums - + 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: @@ -475,7 +473,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. - + ## More Complex Applications @@ -508,4 +506,4 @@ $$ Which is what we were looking for! - + diff --git a/content/3_Silver/Sliding.mdx b/content/3_Silver/Sliding.mdx index 78880e4..26a4cae 100644 --- a/content/3_Silver/Sliding.mdx +++ b/content/3_Silver/Sliding.mdx @@ -11,8 +11,7 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("CSES", "Sum of Two Values", "1141", "Easy", false, []), ], @@ -38,13 +37,12 @@ export const metadata = { qs: [ new Problem("YS","Queue Composite","queue_operate_all_composite","Hard",true,[],""), ], - } }; ## Two Pointers - + Two pointers refers to iterating two monotonic pointers across an array to search for a pair of indices satisfying some condition in linear time. @@ -59,7 +57,7 @@ Two pointers refers to iterating two monotonic pointers across an array to searc ## Sliding Window - + Let's envision a **sliding window** (or constant size subarray) of size $K$ moving left to right along an array, $a$. @@ -78,7 +76,7 @@ To compute the sum in the range, instead of using a set, we can store a variable ### Problems - + ## Sliding Window Minimum in $O(N)$ @@ -88,4 +86,4 @@ To compute the sum in the range, instead of using a set, we can store a variable In particular, the second method allows us to solve the following generalization in linear time as well: - + diff --git a/content/3_Silver/Sorting_2_Old.mdx b/content/3_Silver/Sorting_2_Old.mdx index 73eb90b..e8df3d0 100644 --- a/content/3_Silver/Sorting_2_Old.mdx +++ b/content/3_Silver/Sorting_2_Old.mdx @@ -214,4 +214,4 @@ Comments: Comparator 1 sorts array $a$ in decreasing order. Comparator 2 sorts a ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/3_Silver/Sorting_Custom.mdx b/content/3_Silver/Sorting_Custom.mdx index d3d5899..2f3ec3a 100644 --- a/content/3_Silver/Sorting_Custom.mdx +++ b/content/3_Silver/Sorting_Custom.mdx @@ -10,8 +10,7 @@ description: "Both Java and C++ have built-in functions for sorting. However, if import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("Silver", "Wormhole Sort", "992", "Normal", false, [], ""), ], @@ -25,7 +24,6 @@ export const metadata = { new Problem("Silver", "Triangles", "1015", "Hard", false, [], ""), new Problem("Silver", "Meetings", "967", "Very Hard", false, [], ""), ], - } }; @@ -36,7 +34,7 @@ export const metadata = { ## Example: Wormhole Sort - + 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: @@ -573,4 +571,4 @@ public class Sol { ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/3_Silver/Sorting_Methods.mdx b/content/3_Silver/Sorting_Methods.mdx index 9b56771..bebe63d 100644 --- a/content/3_Silver/Sorting_Methods.mdx +++ b/content/3_Silver/Sorting_Methods.mdx @@ -10,12 +10,10 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { bubble: [ new Problem("Silver", "Out of Sorts", "834", "Very Hard", false, []), ], - } }; @@ -32,7 +30,7 @@ There are many sorting algorithms, here are some sources to learn about the popu ## Bubble Sort - + ### Tutorial diff --git a/content/3_Silver/Sorting_Old.mdx b/content/3_Silver/Sorting_Old.mdx index da6a384..0dcbbef 100644 --- a/content/3_Silver/Sorting_Old.mdx +++ b/content/3_Silver/Sorting_Old.mdx @@ -10,8 +10,7 @@ description: "Both Java and C++ have built-in functions for sorting. However, if import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("Silver", "Wormhole Sort", "992", "Normal", false, [], ""), ], @@ -23,12 +22,11 @@ export const metadata = { new Problem("Silver", "Mooyo Mooyo", "860", "Easy", false, [], "Not a sorting problem, but you can use sorting to simulate gravity. - Write a custom comparator which puts zeroes at the front and use `stable_sort` to keep the relative order of other elements the same."), new Problem("Silver", "Meetings", "967", "Very Hard", false, [], ""), ], - } }; ## Example: Wormhole Sort - + 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. diff --git a/content/3_Silver/Stacks_Queues.mdx b/content/3_Silver/Stacks_Queues.mdx index 084d39c..6a91db0 100644 --- a/content/3_Silver/Stacks_Queues.mdx +++ b/content/3_Silver/Stacks_Queues.mdx @@ -9,8 +9,7 @@ prerequisites: import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { nearest: [ new Problem("CSES", "Nearest Smaller Values", "1645", "Easy", false, [], ""), ], @@ -21,7 +20,6 @@ export const metadata = { new Problem("Gold", "Modern Art 2","743", "Hard", false, [], ""), new Problem("Gold", "Dishwashing","922", "Hard", false, [], ""), ], - } }; ## Additional Reading @@ -224,7 +222,7 @@ pq.add(6); // [7, 6, 5] ## Monotonic Stack - + Consider the following problem: @@ -250,7 +248,7 @@ The stack we used is called a **monotonic stack** because we keep popping off th ## Problems - + ## Hacking @@ -66,4 +64,4 @@ My implementation can be found [here](https://github.com/bqi343/USACO/blob/maste ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/4_Gold/TopoSort.mdx b/content/4_Gold/TopoSort.mdx index 4621229..f6eb257 100644 --- a/content/4_Gold/TopoSort.mdx +++ b/content/4_Gold/TopoSort.mdx @@ -11,8 +11,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("CSES", "Course Schedule", "1679", "Easy", false, []), ], @@ -26,14 +25,13 @@ export const metadata = { new Problem("Gold", "Milking Order", "838", "Normal", false, ["TopoSort", "Binary Search"]), new Problem("CSES", "Course Schedule II", "1681", "Hard", false, [], "equivalent to [Minimal Labels](https://codeforces.com/contest/825/problem/E)"), ], - } }; To review, a **directed** graph consists of edges that can only be traversed in one direction. Additionally, a **acyclic** graph defines a graph which does not contain cycles, meaning you are unable to traverse across one or more edges and return to the node you started on. Putting these definitions together, a **directed acyclic** graph, sometimes abbreviated as DAG, is a graph which has edges which can only be traversed in one direction and does not contain cycles. ## Topological Sort - + 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. @@ -136,7 +134,7 @@ void compute() { 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! - + In this task, we must find the longest path in a DAG. @@ -459,4 +457,4 @@ public class Main { ## Problems - + diff --git a/content/4_Gold/Tree_Euler.mdx b/content/4_Gold/Tree_Euler.mdx index deea958..5c43b7c 100644 --- a/content/4_Gold/Tree_Euler.mdx +++ b/content/4_Gold/Tree_Euler.mdx @@ -12,8 +12,7 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("CSES", "Subtree Queries", "1137", "Easy", false, ["Euler-Tree"], "equivalent to https://judge.yosupo.jp/problem/vertex_add_subtree_sum"), new Problem("CSES", "Path Queries", "1138", "Easy", false, ["Euler-Tree","PURS"], "equivalent to https://judge.yosupo.jp/problem/vertex_add_path_sum"), @@ -29,12 +28,11 @@ export const metadata = { new Problem("ojuz", "IOI - Regions", "IOI09_regions", "Hard", false, ["Euler-Tree", "Binary Search"], ""), new Problem("Plat", "Snow-Cow", "973", "Hard", false, ["Euler-Tree","PURS"], ""), ] - } }; ## Introduction - + 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! @@ -50,7 +48,7 @@ If we can preprocess a rooted tree such that every subtree corresponds to a cont ## LCA - + ### Tutorial @@ -65,4 +63,4 @@ If we can preprocess a rooted tree such that every subtree corresponds to a cont ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Plat/2DRQ.mdx b/content/5_Plat/2DRQ.mdx index 7befc5f..1e5b088 100644 --- a/content/5_Plat/2DRQ.mdx +++ b/content/5_Plat/2DRQ.mdx @@ -8,8 +8,7 @@ description: "Extending Range Queries to 2D (and beyond)." frequency: 1 --- -export const metadata = { - problems: { +export const problems = { bitSam: [ new Problem("CSES", "Forest Queries II", "1739", "Easy", false, ["2D BIT"], "[thecodingwizard's implementation](https://github.com/thecodingwizard/competitive-programming/blob/master/cses/Forest%20Queries%20II.cpp)"), ], @@ -29,7 +28,6 @@ export const metadata = { new Problem("ojuz", "IOI 2013 - Game", "IOI13_game", "Very Hard", false, ["2D Seg"], "Alternatively, use BBST in place of sparse segment tree (see Advanced - Treaps)"), new Problem("ojuz", "JOI - Golf", "JOI17_golf", "Very Hard", false, ["Seg"], ""), ], - } }; See [my implementations](https://github.com/bqi343/USACO/tree/master/Implementations/content/data-structures/2D%20Range%20Queries%20(15.2)). @@ -44,7 +42,7 @@ See [my implementations](https://github.com/bqi343/USACO/tree/master/Implementat ## 2D BIT - + ### Tutorial @@ -55,7 +53,7 @@ See [my implementations](https://github.com/bqi343/USACO/tree/master/Implementat ### Problems - + @@ -67,7 +65,7 @@ Lazy propagation on segment trees does not extend to higher dimensions. However, ## 2D Offline Sum Queries - + 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,7 +91,7 @@ It's a bit difficult to pass the above problem within the time limit. Make sure ### Problems - + ## 2D Segment Tree @@ -124,4 +122,4 @@ To resolve this, reduce the memory usage of sparse segment tree while maintaing Can also try the USACO problems from above. - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Plat/BCC_2CC.mdx b/content/5_Plat/BCC_2CC.mdx index d944287..865ebaf 100644 --- a/content/5_Plat/BCC_2CC.mdx +++ b/content/5_Plat/BCC_2CC.mdx @@ -10,8 +10,7 @@ frequency: 1 --- import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sam2: [ new Problem("YS", "Two-Edge-Connected Components", "two_edge_connected_components", "Easy", false, [], ""), ], @@ -31,7 +30,6 @@ export const metadata = { new Problem("DMOJ", "Investment", "tle17c1p6", "Hard", false, [], ""), new Problem("ojuz", "CEOI - Pipes", "CEOI15_pipes", "Hard", false, [], ""), ], - } }; @@ -40,13 +38,13 @@ export const metadata = { ## 2-Edge-Connected Components - + (implementation) ### With DSU - + 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. @@ -91,7 +89,6 @@ struct TwoEdgeCC { void gen() { F0R(i,N) if (par[i] == -1) dfs(i); // independently for each connected component DSU.init(N); trav(t,extra) ad(t.f,t.s); // add non-spanning edges - } }; ``` @@ -99,13 +96,13 @@ struct TwoEdgeCC { ### Problems - + - SRM 787 1000 ## [Biconnected Components](https://en.wikipedia.org/wiki/Biconnected_component) - + note that BCCs contain EDGES not VERTICES @@ -125,4 +122,4 @@ Related topics include ### Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Plat/Bin_Jump.mdx b/content/5_Plat/Bin_Jump.mdx index 1ba8f46..884db3d 100644 --- a/content/5_Plat/Bin_Jump.mdx +++ b/content/5_Plat/Bin_Jump.mdx @@ -8,8 +8,7 @@ frequency: 3 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("CSES", "Company Queries I", "1687", "Easy", false, ["Binary Jumping"], ""), ], @@ -31,16 +30,15 @@ export const metadata = { new Problem("Plat", "Gathering", "866", "Hard", false, ["LCA"], "interactive!!"), new Problem("Plat", "Exercise", "901", "Very Hard", false, ["LCA"], ""), ] - } }; ## Binary Jumping - + ## Lowest Common Ancestor - + ### Tutorial @@ -59,4 +57,4 @@ export const metadata = { ### Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Plat/Bitsets.mdx b/content/5_Plat/Bitsets.mdx index 77203a8..d478af6 100644 --- a/content/5_Plat/Bitsets.mdx +++ b/content/5_Plat/Bitsets.mdx @@ -10,8 +10,7 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { school: [ new Problem("CSES", "School Excursion", "1706", "Easy", false, ["Knapsack", "Bitset"], ""), ], @@ -29,7 +28,6 @@ export const metadata = { new Problem("CSES", "BOI - Nautilus", "https://cses.fi/247/submit/B", "Normal", false, ["Bitset"], ""), new Problem("ojuz", "IZhO - Bootfall", "IZhO17_bootfall", "Hard", false, ["Knapsack", "Bitset"], ""), ], - } }; ## Tutorial @@ -42,7 +40,7 @@ tl;dr some operations are 32x-64x faster compared to a boolean array. See the [C ## Knapsack - + Of course, the first step is to generate the sizes of each connected component. @@ -103,7 +101,7 @@ int main() { ## Cowpatibility (Gold) - + 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$. @@ -189,7 +187,7 @@ Apparently no test case contains more than $25000$ distinct colors, so we don't ## Lots of Triangles - + 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`. @@ -350,10 +348,10 @@ Operations such as `_Find_first()` and `_Find_next()` mentioned in Errichto's bl Regarding the last application: - + In USACO Camp, this problem appeared with $N\le 10^5$ and a large time limit ... ## Additional Problems - + diff --git a/content/5_Plat/Centroid.mdx b/content/5_Plat/Centroid.mdx index ee04b74..6bff57d 100644 --- a/content/5_Plat/Centroid.mdx +++ b/content/5_Plat/Centroid.mdx @@ -11,8 +11,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const 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"], ""), @@ -26,7 +25,6 @@ export const metadata = { new Problem("ojuz", "JOI - Synchronization", "JOI13_synchronization", "Hard", false, ["Centroid", "Small to Large"], "Looks like $O(N \log^3 N)$ is very fast!"), new Problem("Plat", "At Large", "793", "Very Hard", false, ["Centroid"], "tight time limit"), ] - } }; ## Centroid Decomposition @@ -92,6 +90,6 @@ void centroid(int n = 1) ### Problems - + *Note:* Unfortunately, it seems like constant factor is especially important for DMOJ. :| diff --git a/content/5_Plat/Convex_Hull.mdx b/content/5_Plat/Convex_Hull.mdx index e433f79..4917c08 100644 --- a/content/5_Plat/Convex_Hull.mdx +++ b/content/5_Plat/Convex_Hull.mdx @@ -10,8 +10,7 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("Kattis", "Convex Hull", "convexhull", "Easy", false, ["convex"], ""), ], @@ -32,12 +31,11 @@ export const metadata = { new Problem("Plat", "Circular Barn", "626", "Hard", false, ["DP", "convex"], ""), new Problem("Plat", "Falling Portals", "998", "Very Hard", false, ["convex"], ""), ], - } }; ## [Convex Hull](https://en.wikipedia.org/wiki/Convex_hull_algorithms) - + ### Tutorial @@ -49,17 +47,17 @@ 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) - + ## Rotating Caliphers - + - + ## Convex Hull Trick @@ -68,6 +66,6 @@ export const metadata = { - + https://codeforces.com/contest/1083/problem/E \ No newline at end of file diff --git a/content/5_Plat/DP_Bitmasks.mdx b/content/5_Plat/DP_Bitmasks.mdx index a6be017..f830967 100644 --- a/content/5_Plat/DP_Bitmasks.mdx +++ b/content/5_Plat/DP_Bitmasks.mdx @@ -11,8 +11,7 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { general: [ new Problem("AC", "Matching", "https://atcoder.jp/contests/dp/tasks/dp_o?lang=en", "Easy", false, ["Bitmasks"], ""), new Problem("CSES", "Hamiltonian Flights", "1690", "Easy", false, ["Bitmasks"], ""), @@ -28,7 +27,6 @@ export const metadata = { new Problem("CF", "Guards in the Storehouse", "problemset/problem/845/F", "Normal", false, [], ""), new Problem("Plat", "Compound Escape", "949", "Very Hard", false, [], ""), ], - } }; @@ -48,7 +46,7 @@ You can often use this to solve subtasks. ## Problems - + ## DP on Broken Profile @@ -58,4 +56,4 @@ You can often use this to solve subtasks. (fill in? more probs?) - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Plat/DP_Ranges.mdx b/content/5_Plat/DP_Ranges.mdx index 3cb0eae..1aa9d05 100644 --- a/content/5_Plat/DP_Ranges.mdx +++ b/content/5_Plat/DP_Ranges.mdx @@ -10,8 +10,7 @@ frequency: 2 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { general: [ new Problem("Gold", "248", "647", "Easy", false, ["Range DP"]), new Problem("CSES", "Empty String", "1080", "Normal", false, ["Range DP"]), @@ -19,7 +18,6 @@ export const metadata = { new Problem("Plat", "Greedy Pie Eaters", "972", "Hard", false, ["Range DP"]), new Problem("Plat", "Subsequence Reversal", "698", "Hard", false, ["Range DP"]), ] - } }; ## Tutorial @@ -28,6 +26,6 @@ export const metadata = { ## Problems - + * TC SRM 787 500 diff --git a/content/5_Plat/Eulerian_Tours.mdx b/content/5_Plat/Eulerian_Tours.mdx index 7dd21fe..11f3784 100644 --- a/content/5_Plat/Eulerian_Tours.mdx +++ b/content/5_Plat/Eulerian_Tours.mdx @@ -12,8 +12,7 @@ Has not appeared on a recent USACO contest. import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sam: [ new Problem("CSES", "Mail Delivery (Undirected)", "1691", "Easy", false, ["Euler Tour"], ""), new Problem("CSES", "Teleporters (Directed)", "1693", "Easy", false, ["Euler Tour"], ""), @@ -23,12 +22,11 @@ export const metadata = { new Problem("CF", "Johnny and Megan's Necklace", "contest/1361/problem/C", "Normal", false, ["Euler Tour"], ""), new Problem("CF", "Data Center Drama", "contest/528/problem/C", "Normal", false, ["Euler Tour"], ""), ] - } }; ### Standard - + ### Tutorial @@ -36,4 +34,4 @@ export const metadata = { ### Problems - + diff --git a/content/5_Plat/Eulers_Formula.mdx b/content/5_Plat/Eulers_Formula.mdx index 1ba6acb..c6debb1 100644 --- a/content/5_Plat/Eulers_Formula.mdx +++ b/content/5_Plat/Eulers_Formula.mdx @@ -10,8 +10,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { e1: [ new Problem("DMOJ", "Land of the Rainbow Gold", "apio17p1", "Hard", false, [],""), ], @@ -21,17 +20,16 @@ export const metadata = { other: [ new Problem("Kattis", "Island Archipelago", "https://utipc20s.kattis.com/problems/utipc20s.islandarchipelago", "Very Hard", false, [],""), ], - } }; ## Example 1 - + ## Example 2 - + Extension: - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Plat/Flows.mdx b/content/5_Plat/Flows.mdx index ac7769f..9a0472e 100644 --- a/content/5_Plat/Flows.mdx +++ b/content/5_Plat/Flows.mdx @@ -10,8 +10,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { maxSam: [ new Problem("CSES", "Download Speed", "1694", "Easy", false, ["Max Flow"], ""), ], @@ -35,12 +34,11 @@ export const metadata = { new Problem("CF", "Goods Transportation", "problemset/problem/724/E", "Hard", false, [], ""), new Problem("AC", "ARC E - MUL", "http://arc085.contest.atcoder.jp/tasks/arc085_c", "Hard", false, [], ""), ] - } }; ## Maximum Flow - + ### Tutorial @@ -51,15 +49,15 @@ export const metadata = { ### Problems - + ## Bipartite Matching - + ## Dinic's Algorithm - + Hopcroft-Karp Bipartite Matching? @@ -75,7 +73,7 @@ However, the standard implementation of Dinic's is (almost) always fast enough. ## Min-Cut Max Flow - + (show equivalence) @@ -89,4 +87,4 @@ https://maps20.kattis.com/problems/thewrathofkahn ## Problems - + diff --git a/content/5_Plat/Fracture.mdx b/content/5_Plat/Fracture.mdx index e8eef55..8272064 100644 --- a/content/5_Plat/Fracture.mdx +++ b/content/5_Plat/Fracture.mdx @@ -11,8 +11,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("Plat", "Robotic Cow Herd", "674", "Normal", false, [], ""), ], @@ -21,7 +20,6 @@ export const metadata = { new Problem("DMOJ", "CCO - Shopping Plans", "cco20p6", "Very Hard", false, [], "Generalization of RoboHerd."), new Problem("YS", "K-th Shortest Walk", "k_shortest_walk", "Very Hard", false, [], "(english description?), [Relevant Paper](https://www.ics.uci.edu/~eppstein/pubs/Epp-SJC-98.pdf), Can use to solve RoboHerd!"), ], - } }; @@ -147,7 +145,7 @@ int main() { ## Robotic Cow Herd - + As with the analysis, for each location you should @@ -308,4 +306,4 @@ int main() { ## Other Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Plat/Geo_Pri.mdx b/content/5_Plat/Geo_Pri.mdx index f3bb57b..fecbf4a 100644 --- a/content/5_Plat/Geo_Pri.mdx +++ b/content/5_Plat/Geo_Pri.mdx @@ -7,8 +7,7 @@ description: Basic setup for geometry problems. import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { standard: [ new Problem("YS", "Sort Points by Argument", "sort_points_by_argument", "Intro", false, [], ""), new Problem("Kattis", "Segment Intersection", "segmentintersection", "Intro", false, [], ""), @@ -23,7 +22,6 @@ export const metadata = { new Problem("Kattis", "Max Collinear", "maxcolinear", "Easy", false, [], ""), new Problem("Kattis", "Birthday Cake", "birthdaycake", "Easy", false, [], ""), ] - } }; ## Primitives @@ -50,11 +48,11 @@ You should know basic operations like cross product and dot product. - + ### Misc Problems - + - [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) diff --git a/content/5_Plat/HLD.mdx b/content/5_Plat/HLD.mdx index 3237ea3..f352860 100644 --- a/content/5_Plat/HLD.mdx +++ b/content/5_Plat/HLD.mdx @@ -11,8 +11,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("CSES", "Company Queries II", "1688", "Intro|Easy", false, ["LCA"], "Pure implementation; see Benq's library code, it has a function for LCA. Though this problem can be solved with binary lifting as well, you should do it with HLD to get practice."), ], @@ -28,10 +27,9 @@ export const metadata = { 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"], ""), ], - } }; - + ## Tutorial @@ -50,4 +48,4 @@ export const metadata = { ## Problems - + diff --git a/content/5_Plat/LC.mdx b/content/5_Plat/LC.mdx index 106b008..c29351a 100644 --- a/content/5_Plat/LC.mdx +++ b/content/5_Plat/LC.mdx @@ -10,8 +10,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("YS", "Line Add Get Min", "line_add_get_min", "Normal", false, [], ""), ], @@ -24,7 +23,6 @@ export const metadata = { new Problem("TOKI", "Mall & Transportation", "https://tlx.toki.id/contests/troc-13-div-1/problems/D", "Very Hard", false, [], ""), new Problem("Old Gold", "Fencing the Herd", "534", "Very Hard", false, [], ""), ] - } }; ## Half-Plane Intersection @@ -34,11 +32,11 @@ export const metadata = { expected linear! - + ## LineContainer - + code @@ -48,6 +46,6 @@ export const metadata = { ## Problems - + https://atcoder.jp/contests/arc066/tasks/arc066_d \ No newline at end of file diff --git a/content/5_Plat/Lagrange.mdx b/content/5_Plat/Lagrange.mdx index c9e40b0..92af967 100644 --- a/content/5_Plat/Lagrange.mdx +++ b/content/5_Plat/Lagrange.mdx @@ -10,8 +10,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("Plat", "Tall Barn", "697", "Easy", false, [], ""), ], @@ -20,12 +19,11 @@ export const metadata = { new Problem("Kattis", "Blazing New Trails", "blazingnewtrails", "Normal", false, [], ""), new Problem("ojuz", "Aliens", "IOI16_aliens", "Hard", false, [], ""), ] - } }; adding lambda\*smth - + ## Tutorial @@ -35,4 +33,4 @@ adding lambda\*smth ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Plat/Merging.mdx b/content/5_Plat/Merging.mdx index f94bd07..fbf68c0 100644 --- a/content/5_Plat/Merging.mdx +++ b/content/5_Plat/Merging.mdx @@ -11,8 +11,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sam: [ new Problem("CSES", "Distinct Colors", "1139", "Intro", false, ["Merging"]), ], @@ -23,7 +22,6 @@ export const metadata = { new Problem("Plat", "Disruption", "842", "Normal", false, ["Merging"]), new Problem("POI", "Tree Rotations", "https://szkopul.edu.pl/problemset/problem/sUe3qzxBtasek-RAWmZaxY_p/site/?key=statement", "Normal", false, ["Merging", "Indexed Set"], ""), ], - } }; ## Additional Reading @@ -38,7 +36,7 @@ export const metadata = { Obviously [linked lists](http://www.cplusplus.com/reference/list/list/splice/) can be merged in $O(1)$ time. But what about sets or vectors? - + Let's consider a tree rooted at node $1$, where each node has a color. @@ -122,7 +120,7 @@ A set doesn't have to be an `std::set`. Many data structures can be merged, such ## Problems - + diff --git a/content/5_Plat/Offline_Con.mdx b/content/5_Plat/Offline_Con.mdx index 54c8480..2685d06 100644 --- a/content/5_Plat/Offline_Con.mdx +++ b/content/5_Plat/Offline_Con.mdx @@ -10,8 +10,7 @@ frequency: 0 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { rollback: [ new Problem("YS", "Persistent Union Find", "persistent_unionfind", "Normal", false, [], ""), new Problem("YS", "Vertex Add Component Sum", "dynamic_graph_vertex_add_component_sum", "Hard", false, [], ""), @@ -20,7 +19,6 @@ export const metadata = { ins: [ new Problem("Old Gold", "Fencing the Herd", "534", "Hard", false, [], ""), ], - } }; ### DSU With Rollback @@ -29,7 +27,7 @@ no path compression (tutorial?) - + \ No newline at end of file + --> \ No newline at end of file diff --git a/content/5_Plat/RURQ.mdx b/content/5_Plat/RURQ.mdx index a8ce3c9..aeb9395 100644 --- a/content/5_Plat/RURQ.mdx +++ b/content/5_Plat/RURQ.mdx @@ -10,8 +10,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { bitSample: [ new Problem("SPOJ", "Horrible Queries", "HORRIBLE", "Easy", false, ["BIT-Range"], ""), ], @@ -34,12 +33,11 @@ export const metadata = { segTreeBeats: [ new Problem("YS", "Range Chmin Chmax Add Range Sum", "range_chmin_chmax_add_range_sum", "Very Hard", false, ["SegTreeBeats"], ""), ], - } }; ## BIT Revisited - + Binary Indexed Trees can support range increments in addition to range sum queries. @@ -54,11 +52,11 @@ Binary Indexed Trees can support range increments in addition to range sum queri ### Problems - + ## Lazy Segment Tree - + ### Tutorial @@ -71,7 +69,7 @@ Binary Indexed Trees can support range increments in addition to range sum queri ### Problems - + ## Lazy Segment Tree - Counting Minimums @@ -79,4 +77,4 @@ use segment tree that keeps track of minimum and # of minimums (describe) - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Plat/SCC.mdx b/content/5_Plat/SCC.mdx index 17eb72c..7bbc6b8 100644 --- a/content/5_Plat/SCC.mdx +++ b/content/5_Plat/SCC.mdx @@ -11,8 +11,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { ex: [ new Problem("CSES", "Planets & Kingdoms", "1683", "Easy", false, [], ""), ], @@ -27,12 +26,11 @@ export const metadata = { satEx: [ new Problem("CSES", "Giant Pizza", "1684", "Normal", false, [], "") ], - } }; ## SCCs - + ### Tutorial @@ -49,11 +47,11 @@ export const metadata = { ### Problems - + ## 2-SAT - + (impl) diff --git a/content/5_Plat/SPneg.mdx b/content/5_Plat/SPneg.mdx index 90c7e9a..2dccf2d 100644 --- a/content/5_Plat/SPneg.mdx +++ b/content/5_Plat/SPneg.mdx @@ -10,8 +10,7 @@ frequency: 0 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sam: [ new Problem("Kattis", "SSSP Negative", "shortestpath3", "Easy", false, [], ""), new Problem("Kattis", "APSP (with negative weights)", "allpairspath", "Easy", false, [], ""), @@ -24,10 +23,9 @@ export const metadata = { linear: [ new Problem("ojuz", "Restore Array", "RMI19_restore", "Normal", false, [], "similar to [Art](https://codeforces.com/gym/102394/problem/A)"), ], - } }; - +
@@ -46,7 +44,7 @@ Can also use [Shortest Path Faster Algorithm](https://en.wikipedia.org/wiki/Shor ### Problems - + ## Simple Linear Programming @@ -64,4 +62,4 @@ You can also use shortest path algorithms to solve the following problem (a very ### Problems - + diff --git a/content/5_Plat/Seg_Ext.mdx b/content/5_Plat/Seg_Ext.mdx index 8a06167..78a8058 100644 --- a/content/5_Plat/Seg_Ext.mdx +++ b/content/5_Plat/Seg_Ext.mdx @@ -10,8 +10,7 @@ frequency: 3 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { walkSam: [ new Problem("CSES", "Hotel Queries", "1143", "Easy", false, ["PURQ"], "walk"), ], @@ -35,12 +34,11 @@ export const metadata = { new Problem("Kattis", "Easy Query", "easyquery", "Hard", false, ["Wavelet"], ""), new Problem("DMOJ", "Ninjaclasher's Wrath 2", "globexcup19s4", "Hard", false, ["Wavelet"], ""), ], - } }; ## Walking on a Segment Tree - + You want to support queries of the following form on an array $a_1,\ldots,a_N$ (along with point updates). @@ -48,19 +46,19 @@ 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. - + ## Combining - + (solution to above problem) - + ## Wavelet Tree - + ### Tutorial @@ -70,4 +68,4 @@ Of course, you can do this in $O(\log^2N)$ time with a max segment tree and bina ### Problems - + diff --git a/content/5_Plat/Slope.mdx b/content/5_Plat/Slope.mdx index cc080a5..a7948b0 100644 --- a/content/5_Plat/Slope.mdx +++ b/content/5_Plat/Slope.mdx @@ -11,8 +11,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { ex: [ new Problem("CF", "Problem Without a Legend", "contest/713/problem/C", "Easy", false, ["Slope Trick"], ""), ], @@ -34,7 +33,6 @@ export const metadata = { new Problem("CF", "April Fools' Problem", "contest/802/problem/O", "Very Hard", false, ["Slope Trick"], "binary search on top of slope trick"), new Problem("ICPC World Finals", "Conquer the World", "https://icpc.kattis.com/problems/conquertheworld", "Very Hard", false, ["Slope Trick", "Small to Large"], "ICPC world finals, 0 solves in contest - \"Potatoes\" on tree!!"), ], - } }; ## Tutorials @@ -61,13 +59,13 @@ Usually you can come up with a slower (usually $O(N^2)$) DP first and then optim 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: - + It's ok if you found the explanations confusing; the example below should help clarify. ## Buy Low Sell High - + ### Slow Solution @@ -212,7 +210,7 @@ int main() { ## Potatoes & Fertilizers - + ### Simplifying the Problem @@ -290,7 +288,7 @@ int main() { ## USACO 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. @@ -367,4 +365,4 @@ We can solve this problem when $\sum A_i+\sum B_i$ is not so small with lazy bal ## Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/5_Plat/Sqrt.mdx b/content/5_Plat/Sqrt.mdx index 684b39a..7b88278 100644 --- a/content/5_Plat/Sqrt.mdx +++ b/content/5_Plat/Sqrt.mdx @@ -7,8 +7,7 @@ frequency: 1 --- import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { fst: [ new Problem("CF", "Tree Queries", "contest/1254/problem/D", "Hard", false, [], ""), new Problem("wcipeg", "COI 08-Otoci", "https://wcipeg.com/problem/coi08p2", "Hard", false, ["HLD"], "Editorial rebuilds HLD after certain # of updates ..."), @@ -22,7 +21,6 @@ export const metadata = { other: [ new Problem("Plat", "Train Tracking", "841", "Insane", false, [], ""), ] - } }; @@ -35,7 +33,7 @@ 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 ...) - + ## Mo's @@ -50,7 +48,7 @@ optimization tips? (ez to get TLE with bad constant ..., can get AC with subopti ### Block Tree - + @@ -58,4 +56,4 @@ optimization tips? (ez to get TLE with bad constant ..., can get AC with subopti ### Train Tracking - + diff --git a/content/5_Plat/String_Search.mdx b/content/5_Plat/String_Search.mdx index aa46fda..03af5ad 100644 --- a/content/5_Plat/String_Search.mdx +++ b/content/5_Plat/String_Search.mdx @@ -8,8 +8,7 @@ description: Knuth-Morris-Pratt and Z Algorithms (and a few more related topics) frequency: 1 --- -export const metadata = { - problems: { +export const problems = { KMP: [ new Problem("Kattis", "String Matching", "problems/stringmatching", "Easy", false, ["Strings"], "Naive KMP works. Just be careful about I/O"), new Problem("POJ", "(USACO Gold 05) Cow Patterns", "http://poj.org/problem?id=3167", "Hard", false, ["Strings"], "Run KMP, except each state needs to be considered as not only a length, but also mapping of pattern to # of spots"), @@ -36,7 +35,6 @@ export const metadata = { pal: [ new Problem("ojuz", "Palindrome", "APIO14_palindrome", "Easy", false, [], ""), ] - } }; ## General @@ -59,7 +57,7 @@ Specifically, it computes the longest substring that is both a prefix and suffix - + ## Z Algorithm @@ -71,7 +69,7 @@ The **Z-Algorithm** is another linear time string comparison algorithm like KMP,
- + ## Manacher @@ -88,7 +86,7 @@ It can determine the longest palindrome centered at each character. If s[l, r] is a palindrome, then s[l+1, r-1] is as well. - + # Multiple Strings @@ -104,7 +102,7 @@ This means that every prefix of a string is an ancestor of that string's node.
- + ## Aho-Corasick @@ -122,7 +120,7 @@ Build the entire trie first, and then run a *BFS* to construct the fail array.
- + ## Palindromic Tree @@ -132,6 +130,6 @@ Build the entire trie first, and then run a *BFS* to construct the fail array.
- + DMOJ thing diff --git a/content/5_Plat/Suffix_Array.mdx b/content/5_Plat/Suffix_Array.mdx index da079c0..3059512 100644 --- a/content/5_Plat/Suffix_Array.mdx +++ b/content/5_Plat/Suffix_Array.mdx @@ -10,8 +10,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { sample: [ new Problem("YS", "Suffix Array", "suffixarray", "Easy", false, [], ""), ], @@ -28,7 +27,6 @@ export const metadata = { runSam: [ new Problem("YS", "Run Enumerate", "runenumerate", "Hard", false, [], ""), ] - } }; ## Resources @@ -41,7 +39,7 @@ export const metadata = { ## Suffix Array - + ### Implementations @@ -53,11 +51,11 @@ export const metadata = { ## LCP Array - + Quickly compute longest common prefix of two suffixes. - + ## Inverse Burrows-Wheeler @@ -67,7 +65,7 @@ Quickly compute longest common prefix of two suffixes. CSES Guide? - + ## Run Enumerate @@ -77,5 +75,5 @@ CSES Guide? (describe how to do easily w/ suffix array) - + diff --git a/content/5_Plat/Sweep_Line.mdx b/content/5_Plat/Sweep_Line.mdx index af58bb8..6a6726e 100644 --- a/content/5_Plat/Sweep_Line.mdx +++ b/content/5_Plat/Sweep_Line.mdx @@ -10,8 +10,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { closest: [ new Problem("Kattis", "Closest Pair", "closestpair2", "Normal", false, [], ""), ], @@ -24,7 +23,6 @@ export const metadata = { man: [ new Problem("CSA", "The Sprawl", "the-sprawl", "Hard", false, [], ""), ] - } }; (what's line sweep?) @@ -36,7 +34,7 @@ export const metadata = { ## Closest Pair - + (explanation? KACTL?) @@ -44,18 +42,18 @@ export const metadata = { (refer to previous module) - + (filling in the details?) ## Manhattan MST - + (KACTL code) explanation? topcoder prob has - + TC 760 ComponentsForever \ No newline at end of file diff --git a/content/6_Advanced/Extend_Euclid.mdx b/content/6_Advanced/Extend_Euclid.mdx index 64644c8..51d2c00 100644 --- a/content/6_Advanced/Extend_Euclid.mdx +++ b/content/6_Advanced/Extend_Euclid.mdx @@ -10,8 +10,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { kat: [ new Problem("Kattis","Modular Arithmetic", "modulararithmetic"), ], @@ -19,7 +18,6 @@ export const metadata = { new Problem("Kattis","Chinese Remainder", "chineseremainder"), new Problem("Kattis","Chinese Remainder (non-relatively prime moduli)", "generalchineseremainder"), ], - } }; ## Euclidean Algorithm @@ -140,7 +138,7 @@ Note that this works when $a,b$ are quite large (say, $\approx 2^{60}$) and we w
- + It seems that when multiplication / division is involved in this problem, $n^2 < \texttt{LLONG\_MAX}$. @@ -176,4 +174,4 @@ int main() {
- + diff --git a/content/6_Advanced/FFT-ext.mdx b/content/6_Advanced/FFT-ext.mdx index 2cce889..b4cf619 100644 --- a/content/6_Advanced/FFT-ext.mdx +++ b/content/6_Advanced/FFT-ext.mdx @@ -9,8 +9,7 @@ frequency: 0 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { ys: [ new Problem("YS", "Partition Function", "partition_function", "?", false, [], ""), new Problem("YS", "Bernoulli Number", "bernoulli_number", "?", false, [], ""), @@ -19,7 +18,6 @@ export const metadata = { new Problem("Plat", "Tree Depth", "974", "Hard", false, ["genfunc"], ""), new Problem("Plat", "Exercise", "1045", "Hard", false, ["permutation"], "genfuncs not required but possibly helpful"), ], - } }; ## More Complex Operations @@ -36,13 +34,13 @@ export const metadata = { ### Problems - + ## Counting No advanced knowledge about generating functions is required for either of these problems. - + However, these do: diff --git a/content/6_Advanced/Flow_LB.mdx b/content/6_Advanced/Flow_LB.mdx index a51310b..419b3c1 100644 --- a/content/6_Advanced/Flow_LB.mdx +++ b/content/6_Advanced/Flow_LB.mdx @@ -10,8 +10,7 @@ frequency: 0 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { hungry: [ new Problem("DMOJ", "Hungry Squirrels", "wac4p6", "Normal", false, [], ""), ], @@ -21,10 +20,9 @@ export const metadata = { new Problem("CF", "Incorrect Flow", "contest/708/problem/D", "Normal", false, [], ""), new Problem("AC", "Multi-Path Story", "https://atcoder.jp/contests/jag2013summer-day4/tasks/icpc2013summer_day4_i", "Normal", false, [], ""), ], - } }; - + ### Tutorial @@ -34,4 +32,4 @@ export const metadata = { ### Problems - \ No newline at end of file + \ No newline at end of file diff --git a/content/6_Advanced/LCT.mdx b/content/6_Advanced/LCT.mdx index e925a07..3058bfa 100644 --- a/content/6_Advanced/LCT.mdx +++ b/content/6_Advanced/LCT.mdx @@ -10,8 +10,7 @@ frequency: 1 import { Problem } from "../models"; -export const metadata = { - problems: { +export const problems = { lctSam: [ new Problem("YS", "Vertex Add Path Sum", "dynamic_tree_vertex_add_path_sum", "Normal", false, ["LCT"], ""), ], @@ -38,7 +37,6 @@ export const metadata = { new Problem("CF", "Old Driver Tree", "contest/1172/problem/E", "Hard", false, ["LCT"], ""), new Problem("DMOJ", "Dynamic Tree Test", "ds5", "Very Hard", false, ["LCT"], ""), ] - } }; ## Splay Tree @@ -54,7 +52,7 @@ export const metadata = { ## Link Cut Tree - Paths - + ### Tutorial @@ -65,7 +63,7 @@ export const metadata = { ### Problems - + + module is based off this vectors, strings @@ -279,18 +282,27 @@ for(auto element : v) { -**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. +**Sorting** refers to arranging items in some particular order. + + + + + + + +You should know how to use built-in methods to sort a (possibly dynamic) array. -In order to sort a dynamic array, use `sort(v.begin(), v.end())` (or `sort(begin(v),end(v))`), whereas static arrays require `sort(arr, arr + N)` where $N$ is the number of elements to be sorted. The default sort function sorts the array in ascending order. + + can stop before comparison operators, which are covered in silver + reference + first two related to sorting + - - [std::sort](https://en.cppreference.com/w/cpp/algorithm/sort) - - [std::stable\_sort](http://www.cplusplus.com/reference/algorithm/stable_sort/) - - [Golovanov399 - C++ Tricks](https://codeforces.com/blog/entry/74684) - - first two related to sorting +In order to sort a dynamic array, use `sort(v.begin(), v.end())` (or `sort(begin(v),end(v))`), whereas static arrays require `sort(arr, arr + N)` where $N$ is the number of elements to be sorted. The default sort function sorts the array in ascending order. diff --git a/content/2_Bronze/Intro_Greedy.mdx b/content/2_Bronze/Intro_Greedy.mdx index 35c200f..b9b3585 100644 --- a/content/2_Bronze/Intro_Greedy.mdx +++ b/content/2_Bronze/Intro_Greedy.mdx @@ -2,7 +2,7 @@ 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." +description: "Selecting the choice that seems to be the best at the moment at every step of your algorithm." frequency: 2 --- diff --git a/content/2_Bronze/Pairs_Tuples.mdx b/content/2_Bronze/Pairs_Tuples.mdx index 72ccf1e..70ab3c3 100644 --- a/content/2_Bronze/Pairs_Tuples.mdx +++ b/content/2_Bronze/Pairs_Tuples.mdx @@ -2,7 +2,7 @@ id: pairs-tuples title: Pairs & Tuples author: Benjamin Qi, Nathan Wang, Darren Yao, Abutalib Namazov -description: "Introduction to pairs, which allow you to store two objects (possibly of different types) as a single unit, as well as tuples, which are a generalization of pairs." +description: "Storing two or more objects (possibly of different types) as a single unit." prerequisites: - intro-ds --- @@ -55,18 +55,17 @@ If you sort one of $x_i$ and $y_i$ without considering the other, the points wil Example: ```cpp -#include - +#include using namespace std; int main() { - pair myPair1 = make_pair("Testing", 123); - cout << myPair1.first << " " << myPair1.second << endl; // Testing 123 - myPair1.first = "It is possible to edit pairs after declaring them"; - cout << myPair1.first << " " << myPair1.second << endl; - - pair myPair2 = {"Testing", "curly braces"}; - cout << myPair2.first << " " << myPair2.second << endl; // Testing curly braces + pair myPair1 = make_pair("Testing", 123); + cout << myPair1.first << " " << myPair1.second << endl; // Testing 123 + myPair1.first = "It is possible to edit pairs after declaring them"; + cout << myPair1.first << " " << myPair1.second << endl; + + pair myPair2 = {"Testing", "curly braces"}; + cout << myPair2.first << " " << myPair2.second << endl; // Testing curly braces } /* Output @@ -99,23 +98,20 @@ This is not frequently used by competitive programmers, but it is good to know a Example: ```cpp -#include -#include /// needs additional library -#include - +#include using namespace std; int main() { - int a = 3, b = 4, c = 5; - tuple t = tie(a, b, c); - cout << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << endl; - get<0>(t) = 7; - cout << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << endl; + int a = 3, b = 4, c = 5; + tuple t = tie(a, b, c); + cout << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << endl; + get<0>(t) = 7; + cout << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << endl; - tuple tp2 = make_tuple("Hello", "world", 100); - string s1, s2; int x; - tie(s1, s2, x) = tp2; - cout << s1 << " " << s2 << " " << x << endl; + tuple tp2 = make_tuple("Hello", "world", 100); + string s1, s2; int x; + tie(s1, s2, x) = tp2; + cout << s1 << " " << s2 << " " << x << endl; } /* Output * 3 4 5 @@ -139,12 +135,12 @@ Example from CPH: using namespace std; int main() { - vector> v; - v.push_back({1,5}); - v.push_back({2,3}); - v.push_back({1,2}); - sort(v.begin(), v.end()); - for (pair p: v) cout << p.first << " " << p.second << "\n"; + vector> v; + v.push_back({1,5}); + v.push_back({2,3}); + v.push_back({1,2}); + sort(v.begin(), v.end()); + for (pair p: v) cout << p.first << " " << p.second << "\n"; } /* Output: diff --git a/content/2_Bronze/Time_Comp.mdx b/content/2_Bronze/Time_Comp.mdx index a6e58db..af58746 100644 --- a/content/2_Bronze/Time_Comp.mdx +++ b/content/2_Bronze/Time_Comp.mdx @@ -8,7 +8,7 @@ description: "Evaluating a program's time complexity, or how fast your program r module is based off this Intro and examples - More in-depth. In particular, 5.2 gives a formal definition of Big O. + More in-depth. In particular, 5.2 gives a formal definition of Big O.
@@ -326,11 +326,21 @@ for i in range(m): ## 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) +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$. - + -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)$.) +this is a terrible definition + + + +Normally when using 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)$.) + + + +fix math + + For now, don't worry about how to optimize constant factors -- just be aware of them. diff --git a/content/2_Bronze/Unordered.mdx b/content/2_Bronze/Unordered.mdx index ecf2c29..073fd5b 100644 --- a/content/2_Bronze/Unordered.mdx +++ b/content/2_Bronze/Unordered.mdx @@ -2,7 +2,7 @@ id: unordered title: Unordered Maps & Sets author: Darren Yao, Benjamin Qi -description: "An introduction to unordered maps and sets in multiple languages, two powerful data structures can help simplify bronze problems." +description: "?" frequency: 2 prerequisites: - pairs-tuples diff --git a/content/3_Silver/2P.mdx b/content/3_Silver/2P.mdx new file mode 100644 index 0000000..3ebbbbd --- /dev/null +++ b/content/3_Silver/2P.mdx @@ -0,0 +1,39 @@ +--- +id: 2P +title: "Two Pointers" +author: Darren Yao +prerequisites: +description: "Refers to iterating two monotonic pointers across an array to search for a pair of indices satisfying some condition in linear time." +frequency: 2 +--- + +import { Problem } from "../models"; + +export const problems = { + sample: [ + new Problem("CSES", "Sum of Two Values", "1141", "Easy", false, []), + new Problem("CSES", "Subarray Sums I", "1660", "Easy", false, [], ""), + ], + ad: [ + new Problem("CSES", "Sum of Three Values", "1641", "Easy", false, [], ""), + new Problem("Silver", "Diamond Collector", "643", "Easy", false, ["2P", "Sorting"], ""), + new Problem("Silver", "Sleepy Cow Herding", "918", "Normal", false, ["2P", "Sorting"], ""), + new Problem("CF", "Books", "problemset/problem/279/B", "Normal", false, []), + new Problem("CF", "Cellular Network", "problemset/problem/702/C", "Normal", false, []), + new Problem("CF", "USB vs. PS/2", "problemset/problem/762/B", "Normal", false, []), + new Problem("CF", "K-Good Segment", "problemset/problem/616/D", "Normal", false, []), + new Problem("CF", "Garland", "problemset/problem/814/C", "Normal", false, []), + new Problem("CF", "Jury Meeting", "problemset/problem/853/B", "Normal", false, []), + ], +}; + + + + + solutions to the problems above + + + +## Problems + + \ No newline at end of file diff --git a/content/3_Silver/DFS.mdx b/content/3_Silver/DFS.mdx index b7ea566..1b4fb52 100644 --- a/content/3_Silver/DFS.mdx +++ b/content/3_Silver/DFS.mdx @@ -4,7 +4,7 @@ title: Depth First Search (DFS) author: Siyong Huang prerequisites: - intro-graphs -description: "A way to recursively traverse through a graph." +description: "A way to recursively traverse a graph." frequency: 4 --- diff --git a/content/3_Silver/Func_Graphs.mdx b/content/3_Silver/Func_Graphs.mdx index 7570f2d..42c619b 100644 --- a/content/3_Silver/Func_Graphs.mdx +++ b/content/3_Silver/Func_Graphs.mdx @@ -4,7 +4,7 @@ title: Functional Graphs author: Siyong Huang prerequisites: - dfs -description: "Properties of a functional graphs, directed graphs in which every vertex has exactly one outgoing edge." +description: "Properties of functional graphs, directed graphs in which every vertex has exactly one outgoing edge." frequency: 1 --- diff --git a/content/3_Silver/Harder_Ordered.mdx b/content/3_Silver/Harder_Ordered.mdx index be5d3a9..e503ca2 100644 --- a/content/3_Silver/Harder_Ordered.mdx +++ b/content/3_Silver/Harder_Ordered.mdx @@ -11,119 +11,5 @@ frequency: 2 import { Problem } from "../models"; export const problems = { - sample: [ - new Problem("CSES", "Bit Inversions", "1188", "Normal", false, []), - ], - general: [ - new Problem("Silver", "Milk Measurement", "763", "Normal", false, []), - new Problem("Silver", "Convention II", "859", "Normal", false, []), - new Problem("Gold", "Snow Boots", "813", "Normal", false, []), - new Problem("CF", "Jury Marks", "contest/831/problem/C", "Hard", false, [], "Hard, would recommend skipping (1700 on CF)"), - new Problem("CF", "Mahmoud & Ehab & Function", "contest/862/problem/E", "Hard", false, [], "Hard, do not attempt until Gold/Plat (2100 on CF)"), - new Problem("CF", "Tournament", "contest/878/problem/C", "Very Hard", false, [], "First solve problem for $n$-th tournament only. Extremely hard, do not attempt (2700 on CF)"), - ] }; - -## Example: Using Iterators - - - - - -```cpp -#include -using namespace std; - -#define sz(x) (x).size() - -string s; -int m; -multiset ans, ret; - -void modify(int x) { - if (x == 0 || x == sz(s)) return; - auto it = ans.find(x); - if (it != end(ans)) { - int a = *prev(it), b = *next(it); - ret.erase(ret.find(x-a)), ret.erase(ret.find(b-x)); - ret.insert(b-a); - ans.erase(it); - } else { - it = ans.insert(x); - int a = *prev(it), b = *next(it); - ret.erase(ret.find(b-a)); - ret.insert(x-a), ret.insert(b-x); - } -} - -int main() { - ios_base::sync_with_stdio(0); cin.tie(0); - cin >> s >> m; - ans.insert(0); ans.insert(sz(s)); - for (int i = 0; i < sz(s)-1; ++i) - if (s[i] != s[i+1]) ans.insert(i+1); - for (auto it = ans.begin(); next(it) != ans.end(); it ++) - ret.insert(*next(it)-*it); - for (int i = 0; i < m; ++i) { - int x; cin >> x; - modify(x-1); modify(x); - cout << *ret.rbegin() << " "; - } -} -``` - -
- -Note that `multiset` has a high constant factor, so replacing `ret` with an array and a `priority_queue` reduces the runtime by a factor of 2. - -```cpp -#include -using namespace std; - -#define sz(x) (x).size() - -string s; -int m; -set ans; -priority_queue ret; -int cnt[200005]; - -void ad(int x) { cnt[x] ++; ret.push(x); } -void modify(int x) { - if (x == 0 || x == sz(s)) return; - auto it = ans.find(x); - if (it != end(ans)) { - int a = *prev(it), b = *next(it); ans.erase(it); - cnt[x-a] --, cnt[b-x] --; ad(b-a); - } else { - it = ans.insert(x).first; - int a = *prev(it), b = *next(it); - cnt[b-a] --, ad(x-a), ad(b-x); - } -} - -int main() { - ios_base::sync_with_stdio(0); cin.tie(0); - cin >> s >> m; - ans.insert(0); ans.insert(sz(s)); - for (int i = 0; i < sz(s)-1; ++i) - if (s[i] != s[i+1]) ans.insert(i+1); - for (auto it = ans.begin(); next(it) != ans.end(); it ++) - ad(*next(it)-*it); - for (int i = 0; i < m; ++i) { - int x; cin >> x; - modify(x-1); modify(x); - while (!cnt[ret.top()]) ret.pop(); - cout << ret.top() << " "; - } -} -``` - -
- - - -## Problems - - diff --git a/content/3_Silver/Intro_Ordered.mdx b/content/3_Silver/Intro_Ordered.mdx index bc2e8da..cdc351d 100644 --- a/content/3_Silver/Intro_Ordered.mdx +++ b/content/3_Silver/Intro_Ordered.mdx @@ -4,7 +4,7 @@ title: "Introduction to Ordered Sets" author: Darren Yao, Benjamin Qi prerequisites: - unordered -description: "A data structure that supports quick insertion and deletion by maintaining keys in sorted order." +description: "Data structures that maintain keys in sorted order." frequency: 2 --- @@ -15,6 +15,17 @@ export const problems = { new Problem("CSES", "Concert Tickets", "1091", "Easy", false, ["iterators"], "just do upper_bound"), new Problem("CSES", "Traffic Lights", "1163", "Normal", false, ["set"], "just insert into set one at a time"), ], + sample: [ + new Problem("CSES", "Bit Inversions", "1188", "Normal", false, []), + ], + general: [ + new Problem("Silver", "Milk Measurement", "763", "Normal", false, []), + new Problem("Silver", "Convention II", "859", "Normal", false, []), + new Problem("Gold", "Snow Boots", "813", "Normal", false, []), + new Problem("CF", "Jury Marks", "contest/831/problem/C", "Hard", false, [], "Hard, would recommend skipping (1700 on CF)"), + new Problem("CF", "Mahmoud & Ehab & Function", "contest/862/problem/E", "Hard", false, [], "Hard, do not attempt until Gold/Plat (2100 on CF)"), + new Problem("CF", "Tournament", "contest/878/problem/C", "Very Hard", false, [], "First solve problem for $n$-th tournament only. Extremely hard, do not attempt (2700 on CF)"), + ] }; @@ -251,6 +262,109 @@ next(), prev(), ++, -- -## Standard +## Easy - \ No newline at end of file + + +## Example: Using Iterators + + + + + +```cpp +#include +using namespace std; + +#define sz(x) (x).size() + +string s; +int m; +multiset ans, ret; + +void modify(int x) { + if (x == 0 || x == sz(s)) return; + auto it = ans.find(x); + if (it != end(ans)) { + int a = *prev(it), b = *next(it); + ret.erase(ret.find(x-a)), ret.erase(ret.find(b-x)); + ret.insert(b-a); + ans.erase(it); + } else { + it = ans.insert(x); + int a = *prev(it), b = *next(it); + ret.erase(ret.find(b-a)); + ret.insert(x-a), ret.insert(b-x); + } +} + +int main() { + ios_base::sync_with_stdio(0); cin.tie(0); + cin >> s >> m; + ans.insert(0); ans.insert(sz(s)); + for (int i = 0; i < sz(s)-1; ++i) + if (s[i] != s[i+1]) ans.insert(i+1); + for (auto it = ans.begin(); next(it) != ans.end(); it ++) + ret.insert(*next(it)-*it); + for (int i = 0; i < m; ++i) { + int x; cin >> x; + modify(x-1); modify(x); + cout << *ret.rbegin() << " "; + } +} +``` + +
+ +Note that `multiset` has a high constant factor, so replacing `ret` with an array and a `priority_queue` reduces the runtime by a factor of 2. + +```cpp +#include +using namespace std; + +#define sz(x) (x).size() + +string s; +int m; +set ans; +priority_queue ret; +int cnt[200005]; + +void ad(int x) { cnt[x] ++; ret.push(x); } +void modify(int x) { + if (x == 0 || x == sz(s)) return; + auto it = ans.find(x); + if (it != end(ans)) { + int a = *prev(it), b = *next(it); ans.erase(it); + cnt[x-a] --, cnt[b-x] --; ad(b-a); + } else { + it = ans.insert(x).first; + int a = *prev(it), b = *next(it); + cnt[b-a] --, ad(x-a), ad(b-x); + } +} + +int main() { + ios_base::sync_with_stdio(0); cin.tie(0); + cin >> s >> m; + ans.insert(0); ans.insert(sz(s)); + for (int i = 0; i < sz(s)-1; ++i) + if (s[i] != s[i+1]) ans.insert(i+1); + for (auto it = ans.begin(); next(it) != ans.end(); it ++) + ad(*next(it)-*it); + for (int i = 0; i < m; ++i) { + int x; cin >> x; + modify(x-1); modify(x); + while (!cnt[ret.top()]) ret.pop(); + cout << ret.top() << " "; + } +} +``` + +
+ + + +## Problems + + diff --git a/content/3_Silver/Sliding.mdx b/content/3_Silver/Sliding.mdx deleted file mode 100644 index 26a4cae..0000000 --- a/content/3_Silver/Sliding.mdx +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: sliding -title: "Sliding Window" -author: Darren Yao, Benjamin Qi -prerequisites: - - stacks-queues - - intro-ordered -description: "Moving a subarray across an array to efficently compute information." -frequency: 2 ---- - -import { Problem } from "../models"; - -export const problems = { - sample: [ - new Problem("CSES", "Sum of Two Values", "1141", "Easy", false, []), - ], - slide: [ - new Problem("CSES", "Playlist", "1141", "Easy", false, [],"classic example of 2P"), - ], - general: [ - new Problem("CSES", "Subarray Sums I", "1660", "Easy", false, [], ""), - new Problem("CSES", "Sliding Median", "1076", "Easy", false, [], ""), - new Problem("CSES", "Sliding Cost", "1077", "Hard", false, [], ""), - new Problem("CSES", "Max Subarray Sum II", "1644", "Normal", false, [], ""), - new Problem("Silver", "Diamond Collector", "643", "Easy", false, ["2P", "Sorting"], ""), - new Problem("Silver", "Sleepy Cow Herding", "918", "Normal", false, ["2P", "Sorting"], ""), - new Problem("Gold", "Haybale Feast", "767", "Normal", false, ["Set", "Sliding Window"]), - new Problem("CF", "Books", "problemset/problem/279/B", "Normal", false, []), - new Problem("CF", "Cellular Network", "problemset/problem/702/C", "Normal", false, []), - new Problem("CF", "USB vs. PS/2", "problemset/problem/762/B", "Normal", false, []), - new Problem("CF", "K-Good Segment", "problemset/problem/616/D", "Normal", false, []), - new Problem("CF", "Garland", "problemset/problem/814/C", "Normal", false, []), - new Problem("CF", "Jury Meeting", "problemset/problem/853/B", "Normal", false, []), - new Problem("Plat", "Fort Moo", "600", "Very Hard", false, ["Sliding Window"]), - ], - qs: [ - new Problem("YS","Queue Composite","queue_operate_all_composite","Hard",true,[],""), - ], -}; - - -## Two Pointers - - - -Two pointers refers to iterating two monotonic pointers across an array to search for a pair of indices satisfying some condition in linear time. - - - - - - -### Implementation - - - -## Sliding Window - - - -Let's envision a **sliding window** (or constant size subarray) of size $K$ moving left to right along an array, $a$. - -For each position of the window, we want to compute some information. For example, we could store an ordered set of integers representing the integers inside the window. If the window currently spans the range $i \dots j$, we observe that moving the range forward to $i+1 \dots j+1$ only removes $a_i$ and adds $a_{j+1}$ to the window. We can support these two operations and query for the minimum / maximum in the set in $O(\log N)$. - -To compute the sum in the range, instead of using a set, we can store a variable $s$ representing the sum. As we move the window forward, we update $s$ by subtracting $a_i$ from $s$ and adding $a_{j+1}$ to $s$. - - - - - - -### Implementation - - - -### Problems - - - -## Sliding Window Minimum in $O(N)$ - - - Mentions two ways to solve this (both are important)! - - -In particular, the second method allows us to solve the following generalization in linear time as well: - - diff --git a/content/3_Silver/Sorting_Custom.mdx b/content/3_Silver/Sorting_Custom.mdx index 9ed5064..bb574e8 100644 --- a/content/3_Silver/Sorting_Custom.mdx +++ b/content/3_Silver/Sorting_Custom.mdx @@ -6,7 +6,7 @@ author: Darren Yao, Siyong Huang, Michael Cao, Benjamin Qi prerequisites: - pairs-tuples - lambda -description: "Both Java and C++ have built-in functions for sorting. However, if we use custom objects, or if we want to sort elements in a different order, then we'll need to use a custom comparator." +description: "If we use custom objects or if we want to sort elements in an order other than the default, then we'll need to define a custom comparator." --- import { Problem } from "../models"; diff --git a/content/4_Gold/Faster_Hash.mdx b/content/4_Gold/Faster_Hash.mdx index a36d4b9..3e64bc1 100644 --- a/content/4_Gold/Faster_Hash.mdx +++ b/content/4_Gold/Faster_Hash.mdx @@ -14,6 +14,9 @@ export const problems = { three: [ new Problem("Gold", "3SUM", "994", "Normal", false, [], ""), ], + four: [ + new Problem("CSES", "Sum of Four Values", "1642", "Normal", false, [], ""), + ], }; @@ -104,9 +107,9 @@ You're supposed to use array since values are small :| using namespace std; void setIO(string name) { - ios_base::sync_with_stdio(0); cin.tie(0); - freopen((name+".in").c_str(),"r",stdin); - freopen((name+".out").c_str(),"w",stdout); + ios_base::sync_with_stdio(0); cin.tie(0); + freopen((name+".in").c_str(),"r",stdin); + freopen((name+".out").c_str(),"w",stdout); } @@ -118,27 +121,31 @@ long long ans[5000][5000]; vector A; int main() { - setIO("threesum"); - cin >> N >> Q; - A.resize(N); for (int i = 0; i < N; ++i) cin >> A[i]; - for (int i = 0; i < N; ++i) { - gp_hash_table g({},{},{},{},{1<<13}); - // initialize with certain capacity, must be power of 2 - for (int j = i+1; j < N; ++j) { - int res = -A[i]-A[j]; - auto it = g.find(res); - if (it != end(g)) ans[i][j] = it->second; - g[A[j]] ++; - } - } - for (int i = N-1; i >= 0; --i) for (int j = i+1; j < N; ++j) - ans[i][j] += ans[i+1][j]+ans[i][j-1]-ans[i+1][j-1]; - for (int i = 0; i < Q; ++i) { - int a,b; cin >> a >> b; - cout << ans[a-1][b-1] << "\n"; - } - // you should actually read the stuff at the bottom + setIO("threesum"); + cin >> N >> Q; + A.resize(N); for (int i = 0; i < N; ++i) cin >> A[i]; + for (int i = 0; i < N; ++i) { + gp_hash_table g({},{},{},{},{1<<13}); + // initialize with certain capacity, must be power of 2 + for (int j = i+1; j < N; ++j) { + int res = -A[i]-A[j]; + auto it = g.find(res); + if (it != end(g)) ans[i][j] = it->second; + g[A[j]] ++; + } + } + for (int i = N-1; i >= 0; --i) for (int j = i+1; j < N; ++j) + ans[i][j] += ans[i+1][j]+ans[i][j-1]-ans[i+1][j-1]; + for (int i = 0; i < Q; ++i) { + int a,b; cin >> a >> b; + cout << ans[a-1][b-1] << "\n"; + } + // you should actually read the stuff at the bottom } ``` - \ No newline at end of file + + +## Problems + + \ No newline at end of file diff --git a/content/4_Gold/Queues.mdx b/content/4_Gold/Queues.mdx new file mode 100644 index 0000000..af8f927 --- /dev/null +++ b/content/4_Gold/Queues.mdx @@ -0,0 +1,126 @@ +--- +id: queues +title: Queues +author: Darren Yao +description: "Two data structures to efficently add and remove the first and last element." +prerequisites: + - intro-ds + - sliding +--- + +import { Problem } from "../models"; + +export const problems = { + ys: [ + new Problem("YS","Persistent Queue","persistent_queue","Normal",false,["DFS"],""), + new Problem("YS","Queue Composite","queue_operate_all_composite","Hard",true,[],""), + ], + sam: [ + new Problem("LC", "Sliding Window Maximum", "sliding-window-maximum", "Easy", false, [], ""), + ], +}; + +## Queues + +A queue is a First In First Out (FIFO) data structure that supports three operations, all in $O(1)$ time. + + + + + +### [C++](http://www.cplusplus.com/reference/queue/queue/) + + - `push`: insertion at the back of the queue + - `pop`: deletion from the front of the queue + - `front`: which retrieves the element at the front without removing it. + +```cpp +queue q; +q.push(1); // [1] +q.push(3); // [3, 1] +q.push(4); // [4, 3, 1] +q.pop(); // [4, 3] +cout << q.front() << endl; // 3 +``` + + + + + +### Java + + - `add`: insertion at the back of the queue + - `poll`: deletion from the front of the queue + - `peek`: which retrieves the element at the front without removing it + +Java doesn't actually have a `Queue` class; it's only an interface. The most commonly used implementation is the `LinkedList`, declared as follows: + +```java +Queue q = new LinkedList(); +q.add(1); // [1] +q.add(3); // [3, 1] +q.add(4); // [4, 3, 1] +q.poll(); // [4, 3] +System.out.println(q.peek()); // 3 +``` + + + + + +## Deques + +A **deque** (usually pronounced "deck") stands for double ended queue and is a combination of a stack and a queue, in that it supports $O(1)$ insertions and deletions from both the front and the back of the deque. Not very common in Bronze / Silver. + + + + + +### [C++](http://www.cplusplus.com/reference/deque/deque/) + +The four methods for adding and removing are `push_back`, `pop_back`, `push_front`, and `pop_front`. + +```cpp +deque d; +d.push_front(3); // [3] +d.push_front(4); // [4, 3] +d.push_back(7); // [4, 3, 7] +d.pop_front(); // [3, 7] +d.push_front(1); // [1, 3, 7] +d.pop_back(); // [1, 3] +``` + + + + + +### Java + +In Java, the deque class is called `ArrayDeque`. The four methods for adding and removing are `addFirst` , `removeFirst`, `addLast`, and `removeLast`. + +```java +ArrayDeque deque = new ArrayDeque(); +deque.addFirst(3); // [3] +deque.addFirst(4); // [4, 3] +deque.addLast(7); // [4, 3, 7] +deque.removeFirst(); // [3, 7] +deque.addFirst(1); // [1, 3, 7] +deque.removeLast(); // [1, 3] +``` + + + + + +## Sliding Window Minimum in $O(N)$ + + + + + + Mentions two ways to solve this (both are important)! + + +## Problems + + \ No newline at end of file diff --git a/content/4_Gold/Sliding.mdx b/content/4_Gold/Sliding.mdx new file mode 100644 index 0000000..cef38e5 --- /dev/null +++ b/content/4_Gold/Sliding.mdx @@ -0,0 +1,61 @@ +--- +id: sliding +title: "Sliding Window" +author: Darren Yao, Benjamin Qi +prerequisites: + - intro-ordered + - 2P +description: "Maintaining data over consecutive subarrays." +frequency: 2 +--- + +import { Problem } from "../models"; + +export const problems = { + constantSam: [ + new Problem("LC", "Sliding Window Maximum", "sliding-window-maximum", "Easy", false, [], ""), + ], + constant: [ + new Problem("CSES", "Max Subarray Sum II", "1644", "Normal", false, ["prefix-sums"], ""), + new Problem("CSES", "Sliding Median", "1076", "Normal", false, [], ""), + new Problem("CSES", "Sliding Cost", "1077", "Hard", false, [], ""), + ], + general: [ + new Problem("CSES", "Playlist", "1141", "Easy", false, ["2P"], ""), + new Problem("Gold", "Haybale Feast", "767", "Easy", false, ["Set", "Sliding Window"]), + new Problem("Plat", "Fort Moo", "600", "Hard", false, ["Sliding Window"]), + ] +}; + +## Sliding Window + + + +From CPH: + +> A sliding window is a constant-size subarray that moves from left to right +through the array. + +For each position of the window, we want to compute some information. For example, we could store an ordered set of integers representing the integers inside the window. If the window currently spans the range $i \dots j$, we observe that moving the range forward to $i+1 \dots j+1$ only removes $a_i$ and adds $a_{j+1}$ to the window. We can support these two operations and query for the minimum / maximum in the set in $O(\log N)$. + + + + + + + + +### Implementation + + + +### Problems + + + +## With Two Pointers + +In general, it is not required for the subarray to have constant size as long as both the left and right endpoints of the subarray only move to the right. + + \ No newline at end of file diff --git a/content/3_Silver/Stacks_Queues.mdx b/content/4_Gold/Stacks.mdx similarity index 59% rename from content/3_Silver/Stacks_Queues.mdx rename to content/4_Gold/Stacks.mdx index 96ec82f..4f69639 100644 --- a/content/3_Silver/Stacks_Queues.mdx +++ b/content/4_Gold/Stacks.mdx @@ -1,6 +1,6 @@ --- -id: stacks-queues -title: Introduction to Stacks & Queues +id: stacks +title: Stacks author: Darren Yao description: "Two data structures to efficently add and remove the first and last element." prerequisites: @@ -16,14 +16,11 @@ export const problems = { general: [ new Problem("LC", "Max Histogram Area", "largest-rectangle-in-histogram", "Normal", false, [],""), new Problem("Old Gold", "Concurrently Balanced Strings", "194", "Normal", false, [],""), - new Problem("YS","Persistent Queue","persistent_queue","Normal",false,["DFS"],""), new Problem("Gold", "Modern Art 2","743", "Hard", false, [], ""), new Problem("Gold", "Dishwashing","922", "Hard", false, [], ""), ], }; -## Additional Reading - @@ -79,101 +76,8 @@ System.out.println(s.size()); // 2
-## Queues -A queue is a First In First Out (FIFO) data structure that supports three operations, all in $O(1)$ time. - - - - - -### [C++](http://www.cplusplus.com/reference/queue/queue/) - - - `push`: insertion at the back of the queue - - `pop`: deletion from the front of the queue - - `front`: which retrieves the element at the front without removing it. - -```cpp -queue q; -q.push(1); // [1] -q.push(3); // [3, 1] -q.push(4); // [4, 3, 1] -q.pop(); // [4, 3] -cout << q.front() << endl; // 3 -``` - - - - - -### Java - - - `add`: insertion at the back of the queue - - `poll`: deletion from the front of the queue - - `peek`: which retrieves the element at the front without removing it - -Java doesn't actually have a `Queue` class; it's only an interface. The most commonly used implementation is the `LinkedList`, declared as follows: - -```java -Queue q = new LinkedList(); -q.add(1); // [1] -q.add(3); // [3, 1] -q.add(4); // [4, 3, 1] -q.poll(); // [4, 3] -System.out.println(q.peek()); // 3 -``` - - - - - -## Deques - -A **deque** (usually pronounced "deck") stands for double ended queue and is a combination of a stack and a queue, in that it supports $O(1)$ insertions and deletions from both the front and the back of the deque. Not very common in Bronze / Silver. - - - - - -### [C++](http://www.cplusplus.com/reference/deque/deque/) - -The four methods for adding and removing are `push_back`, `pop_back`, `push_front`, and `pop_front`. - -```cpp -deque d; -d.push_front(3); // [3] -d.push_front(4); // [4, 3] -d.push_back(7); // [4, 3, 7] -d.pop_front(); // [3, 7] -d.push_front(1); // [1, 3, 7] -d.pop_back(); // [1, 3] -``` - - - - - -### Java - -In Java, the deque class is called `ArrayDeque`. The four methods for adding and removing are `addFirst` , `removeFirst`, `addLast`, and `removeLast`. - -```java -ArrayDeque deque = new ArrayDeque(); -deque.addFirst(3); // [3] -deque.addFirst(4); // [4, 3] -deque.addLast(7); // [4, 3, 7] -deque.removeFirst(); // [3, 7] -deque.addFirst(1); // [1, 3, 7] -deque.removeLast(); // [1, 3] -``` - - - - - - - -## Monotonic Stack +## Application: Nearest Smaller Element @@ -181,24 +85,22 @@ Consider the following problem: > Given an array, $a$, of $N$ ($1 \le N \le 10^5$) integers, for every index $i$, find the rightmost index $j$ such that $j < i$ and $a_i > a_j$. -To solve this, let's store a stack of pairs of `` and iterate over the array from left to right. For some index $i$, we will compute $ans_i$, the rightmost index for $i$, as follows: + + + + + +To solve this, let's store a stack of pairs of `` and iterate over the array from left to right. For some index $i$, we will compute $ans_i$, the rightmost index for $i$, as follows: - Keep popping the top element off the stack as long as $value \ge a_i$. This is because we know that the pair containing $value$ will never be the solution to any index $j > i$, since $a_i$ is less than or equal to than $value$ and has an index further to the right. - If $value < a_i$, set $ans[i]$ to $index$, because a stack stores the most recently added values first (or in this case, the rightmost ones), $index$ will contain the rightmost value which is less than $a_i$. Then, pop the top element off the stack, because $index$ can't be the solution for two elements. The stack we used is called a **monotonic stack** because we keep popping off the top element of the stack which maintains it's monotonicity (the same property needed for algorithms like binary search) because the elements in the stack are increasing. -(add code) +### Implementation -### Further Reading - - - - - - ## Problems diff --git a/content/ordering.ts b/content/ordering.ts index e9ac45b..59930fc 100644 --- a/content/ordering.ts +++ b/content/ordering.ts @@ -95,18 +95,23 @@ const MODULE_ORDERING: {[key in SectionID]: Category[]} = { ] }, { - name: "Binary Search", + name: "Sorting", items: [ "binary-search-sorted", - "binary-search-ans", + "sorting-custom", + "greedy", ] }, { - name: "Sorting", + name: "Two Pointers", items: [ - "sorting-methods", - "sorting-custom", - "greedy", + "2P", + ] + }, + { + name: "Binary Search", + items: [ + "binary-search-ans", ] }, { @@ -114,14 +119,6 @@ const MODULE_ORDERING: {[key in SectionID]: Category[]} = { items: [ "intro-ordered", "custom-cpp-stl", - "harder-ordered", - ] - }, - { - name: "Stacks & Queues", - items: [ - "stacks-queues", - "sliding", ] }, { @@ -134,6 +131,14 @@ const MODULE_ORDERING: {[key in SectionID]: Category[]} = { }, ], "gold": [ + { + name: "Data Structures", + items: [ + "stacks", + "sliding", + "queues", + ] + }, { name: "Dynamic Programming", items: [