diff --git a/content/4_Silver/Binary_Search.md b/content/4_Silver/Binary_Search.md
index 5fb2b1f..2afff8a 100644
--- a/content/4_Silver/Binary_Search.md
+++ b/content/4_Silver/Binary_Search.md
@@ -2,20 +2,137 @@
id: binary-search
title: "Binary Search on the Answer"
author: Darren Yao
+ -
+ - Silver - Introduction to Sorting
---
-## Binary Searching on the Answer
+You should already be familiar with the concept of **binary searching** for a number in a sorted array. However, binary search can be extended to binary searching on the answer itself.
-Oftentimes used when you need to find the minimum or maximum of some quantity such that it satisfies some property.
-
-### Tutorial
+
- - Intro to USACO 12.1
+When we binary search on the answer, we start with a search space of size $N$ which we know the answer lies in. Then, each iteration of the binary search cuts the search space in half, so the algorithm tests $O(\log N)$ values. This is efficient and much better than testing each possible value in the search space.
+
+Let's say we have a function `check(x)` that returns true if the answer of $x$ is possible, and false otherwise. Usually, in such problems, we'll want to find the maximum or minimum value of $x$ such that `check(x)` is true. Similarly to how binary search on an array only works on a sorted array, binary search on the answer only works if the answer function is [monotonic](https://en.wikipedia.org/wiki/Monotonic_function), meaning that it is always non-decreasing or always non-increasing.
+
+In particular, if we want to find the maximum `x` such that `check(x)` is true, then we can binary search if `check(x)` satisfies both of the following conditions:
+
+ - If `check(x)` is `true`, then `check(y)` is true for all $y \leq x$.
+ - If `check(x)` is `false`, then `check(y)` is false for all $y \geq x$.
+
+In other words, we want to reduce the search space to something of the following form, using a check function as we described above.
+
+
true true true true true false false false false
+
+We want to find the point at which `true` becomes `false`.
+
+Below, we present two algorithms for binary search. The first implementation may be more intuitive, because it's closer to the binary search most students learned, while the second implementation is shorter.
+
+(pseudocode)
+
+If instead we're looking for the minimum `x` that satisfies some condition, then we can binary search if `check(x)` satisfies both of the following conditions:
+
+ - If `check(x)` is true, then `check(y)` is true for all $y \geq x$.
+ - If `check(x)` is false, then `check(y)` is false for all $y \leq x$.
+
+The binary search function for this is very similar. Find the maximum value of $x$ such that `check(x)` is false with the algorithm above, and return $x+1$.
+
+## Example: [CF 577 Div. 2 C](https://codeforces.com/contest/1201/problem/C)
+
+Given an array `arr` of $n$ integers, where $n$ is odd, we can perform the following operation on it $k$ times: take any element of the array and increase it by $1$. We want to make the median of the array as large as possible, after $k$ operations.
+
+Constraints: $1 \leq n \leq 2 \cdot 10^5, 1 \leq k \leq 10^9$ and $n$ is odd.
+
+The solution is as follows: we first sort the array in ascending order. Then, we binary search for the maximum possible median. We know that the number of operations required to raise the median to $x$ increases monotonically as $x$ increases, so we can use binary search. For a given median value $x$, the number of operations required to raise the median to $x$ is
+
+$$\sum_{i=(n+1)/2}^{n} \max(0, x - \text{arr[i]}})$$
+
+If this value is less than or equal to $k$, then $x$ can be the median, so our check function returns true. Otherwise, $x$ cannot be the median, so our check function returns false.
+
+The solution codes use the second implementation of binary search.
+
+Java:
+```java
+static int n;
+static long k;
+static long[] arr;
+public static void main(String[] args) {
+
+ n = r.nextInt(); k = r.nextLong();
+ arr = new long[n];
+ for(int i = 0; i < n; i++){
+ arr[i] = r.nextLong();
+ }
+ Arrays.sort(arr);
+
+ pw.println(search());
+ pw.close();
+}
+
+// binary searches for the correct answer
+static long search(){
+ long pos = 0; long max = (long)2E9;
+ for(long a = max; a >= 1; a /= 2){
+ while(check(pos+a)) pos += a;
+ }
+ return pos;
+}
+
+// checks whether the number of given operations is sufficient
+// to raise the median of the array to x
+static boolean check(long x){
+ long operationsNeeded = 0;
+ for(int i = (n-1)/2; i < n; i++){
+ operationsNeeded += Math.max(0, x-arr[i]);
+ }
+ if(operationsNeeded <= k){ return true; }
+ else{ return false; }
+}
+```
+
+C++:
+
+```cpp
+int n;
+long long k;
+vector v;
+
+// checks whether the number of given operations is sufficient
+// to raise the median of the array to x
+bool check(long long x){
+ long long operationsNeeded = 0;
+ for(int i = (n-1)/2; i < n; i++){
+ operationsNeeded += max(0, x-v[i]);
+ }
+ if(operationsNeeded <= k) return true;
+ else return false;
+}
+
+// binary searches for the correct answer
+long long search(){
+ long long pos = 0; long long max = 2E9;
+ for(long long a = max; a >= 1; a /= 2){
+ while(check(pos+a)) pos += a;
+ }
+ return pos;
+}
+
+int main() {
+ cin >> n >> k;
+ for(int i = 0; i < n; i++){
+ int t;
+ cin >> t;
+ v.push_back(t);
+ }
+ sort(v.begin(), v.end());
+
+ cout << search() << '\n';
+}
+```
### Problems
- USACO
- - [USACO Silver - Cow Dance](http://www.usaco.org/index.php?page=viewproblem2&cpid=690)
+ - [USACO Silver - Cow Dance Show](http://www.usaco.org/index.php?page=viewproblem2&cpid=690)
- binary search on $K$ and simulate
- [USACO Silver - Convention](http://www.usaco.org/index.php?page=viewproblem2&cpid=858)
- determine whether $M$ buses suffice if every cow waits at most $T$ minutes
diff --git a/content/4_Silver/Prefix_Sums.md b/content/4_Silver/Prefix_Sums.md
index 0105b41..7ff7180 100644
--- a/content/4_Silver/Prefix_Sums.md
+++ b/content/4_Silver/Prefix_Sums.md
@@ -89,3 +89,7 @@ Which is what we were looking for!
- [AtCoder Multiple of 2019](https://atcoder.jp/contests/abc164/tasks/abc164_d)
- [Google Kick Start Candies](https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ff43/0000000000337b4d) (**only** Test Set 1.)
+
+## Additional Problems
+
+ - [CF Edu Round 60 C: Magic Ship](https://codeforces.com/problemset/problem/1117/C)
\ No newline at end of file
diff --git a/content/5_Gold/DP.md b/content/5_Gold/DP.md
index 3ae56c1..6152562 100644
--- a/content/5_Gold/DP.md
+++ b/content/5_Gold/DP.md
@@ -79,11 +79,6 @@ The following USACO problems don't fall into any of the categories below. Arrang
* straightforward
* [Talent Show](http://www.usaco.org/index.php?page=viewproblem2&cpid=839)
* binary search + knapsack on weight
- * [Cow Poetry](http://usaco.org/index.php?page=viewproblem2&cpid=897)
- * First consider the case where there are only two lines with the same class.
- * Requires fast modular exponentiation for full credit.
- * [Exercise](http://www.usaco.org/index.php?page=viewproblem2&cpid=1043)
- * With a bit of number theory
* CF
* [Round Subset](http://codeforces.com/contest/837/problem/D) [](59)
* [Fire](http://codeforces.com/contest/864/problem/E) [](59)
diff --git a/content/5_Gold/Intro_NT.md b/content/5_Gold/Intro_NT.md
index 95289c6..a063fba 100644
--- a/content/5_Gold/Intro_NT.md
+++ b/content/5_Gold/Intro_NT.md
@@ -1,46 +1,98 @@
---
id: intro-nt
title: "Introductory Number Theory"
-author: Unknown
+author: Darren Yao
---
-
- Description: Todo
-
+ - Prime Factorization
+ - GCD & LCM
+ - Modular Arithmetic
-See 13 of https://www.overleaf.com/project/5e73f65cde1d010001224d8a
+## Additional Resources
-- Prime factorization, GCD, LCM
-- Modular Arithmetic
+ - CSES 21.1, 21.2
+ - [CF CodeNCode](https://codeforces.com/blog/entry/77137)
-Also see here: https://codeforces.com/blog/entry/77137
+## Prime Factorization
-# Binary Exponentiation
+A number $a$ is called a **divisor** or a **factor** of a number $b$ if $b$ is divisible by $a$, which means that there exists some integer $k$ such that $b = ka$. Conventionally, $1$ and $n$ are considered divisors of $n$. A number $n > 1$ is **prime** if its only divisors are $1$ and $n$. Numbers greater than \(1\) that are not prime are **composite**.
-
+Every number has a unique **prime factorization**: a way of decomposing it into a product of primes, as follows:
+\[ n = {p_1}^{a_1} {p_2}^{a_2} \cdots {p_k}^{a_k} \]
+where the $p_i$ are distinct primes and the $a_i$ are positive integers.
- - Tutorial
- - CPH (23, Matrices)
- - Problems
- - [Currencies](https://www.hackerrank.com/contests/gs-codesprint/challenges/currencies) [](107)
+Now, we will discuss how to find the prime factorization of an integer.
-COWBASIC
+(pseudocode)
-(old)
+This algorithm runs in $O(\sqrt{n})$ time, because the for loop checks divisibility for at most $\sqrt{n}$ values. Even though there is a while loop inside the for loop, dividing $n$ by $i$ quickly reduces the value of $n$, which means that the outer for loop runs less iterations, which actually speeds up the code.
+
+Let's look at an example of how this algorithm works, for $n = 252$.
+
+(table)
+
+At this point, the for loop terminates, because $i$ is already 3 which is greater than $\lfloor \sqrt{7} \rfloor$. In the last step, we add $7$ to the list of factors $v$, because it otherwise won't be added, for a final prime factorization of $\{2, 2, 3, 3, 7\}$.
-### 4
+## GCD & LCM
- * Eratosthenes' Sieve
- * Tutorial
- * CPH (21, NT)
+The **greatest common divisor (GCD)** of two integers $a$ and $b$ is the largest integer that is a factor of both $a$ and $b$. In order to find the GCD of two numbers, we use the Euclidean Algorithm, which is as follows:
-### 5
+$$\gcd(a, b) = \begin{cases}
+ a & b = 0 \\
+ \gcd(b, a \bmod b) & b \neq 0 \\
+ \end{cases}$$
- * Modular Arithmetic
- * Modular Inverse
- * Chinese Remainder Theorem
- * Euler's Theorem, Phi Function
- * Discrete Logarithm
\ No newline at end of file
+This algorithm is very easy to implement using a recursive function in Java, as follows:
+
+```java
+public int gcd(int a, int b){
+ if(b == 0) return a;
+ return gcd(b, a % b);
+}
+```
+
+For C++, use the built-in `__gcd(a,b)`. Finding the GCD of two numbers can be done in $O(\log n)$ time, where $n = \min(a, b)$.
+
+The **least common multiple (LCM)** of two integers $a$ and $b$ is the smallest integer divisible by both $a$ and $b$.
+
+The LCM can easily be calculated from the following property with the GCD:
+
+$$\operatorname{lcm}(a, b) = \frac{a \cdot b}{\gcd(a, b)}$$
+
+If we want to take the GCD or LCM of more than two elements, we can do so two at a time, in any order. For example,
+
+$$\gcd(a_1, a_2, a_3, a_4) = \gcd(a_1, \gcd(a_2, \gcd(a_3, a_4)))$$
+
+## Modular Arithmetic
+
+In **modular arithmetic**, instead of working with integers themselves, we work with their remainders when divided by $m$. We call this taking modulo $m$. For example, if we take $m = 23$, then instead of working with $x = 247$, we use $x \bmod 23 = 17$. Usually, $m$ will be a large prime, given in the problem; the two most common values are $10^9 + 7$, and $998\,244\,353$. Modular arithmetic is used to avoid dealing with numbers that overflow built-in data types, because we can take remainders, according to the following formulas:
+
+$$\begin{gather*}
+ (a+b) \bmod m = (a \bmod m + b \bmod m) \bmod m \\
+ (a-b) \bmod m = (a \bmod m - b \bmod m) \bmod m \\
+ (a \cdot b) \pmod{m} = ((a \bmod m) \cdot (b \bmod m)) \bmod m \\
+ a^b \bmod {m} = (a \bmod m)^b \bmod m
+\end{gather*}$$
+
+### Modular Exponentiation
+
+?
+
+### Modular Inverse
+
+Under a prime moduli, division exists.
+
+## Problems
+
+ - USACO
+ - Both are also Knapsack DP problems.
+ - [Cow Poetry](http://usaco.org/index.php?page=viewproblem2&cpid=897)
+ - First consider the case where there are only two lines with the same class.
+ - Requires fast modular exponentiation for full credit.
+ - [Exercise](http://www.usaco.org/index.php?page=viewproblem2&cpid=1043)
+ - Prime factorization
+ - Other
+ - [CF VK Cup 2012 Wildcard Round 1 C](https://codeforces.com/problemset/problem/162/C)
\ No newline at end of file
diff --git a/content/ordering.js b/content/ordering.js
index d1d0bba..3fb6498 100644
--- a/content/ordering.js
+++ b/content/ordering.js
@@ -49,8 +49,6 @@ const ModuleOrdering = {
"dfs"
],
"gold": [
- "intro-nt",
- "bit",
{
name: "Graphs",
items: [
@@ -67,6 +65,8 @@ const ModuleOrdering = {
"dp-trees"
]
}
+ "intro-nt",
+ "bit",
],
"plat": [
"oly",