diff --git a/CODEOWNERS b/CODEOWNERS index 116b1ff783..7a314e15b8 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -8,11 +8,11 @@ /solutions/bronze/ @SansPapyrus683 @ryanchou-dev /content/3_Silver/ @SansPapyrus683 @ryanchou-dev /solutions/silver/ @SansPapyrus683 @ryanchou-dev -/content/4_Gold/ @dongliu0426 @envyaims -/solutions/gold/ @dongliu0426 @envyaims -/content/5_Plat/ @dustin-miao @dongliu0426 -/solutions/platinum/ @dustin-miao @dongliu0426 -/content/6_Advanced/ @dustin-miao @dongliu0426 -/solutions/advanced/ @dustin-miao @dongliu0426 +/content/4_Gold/ @dongliuu @envyaims +/solutions/gold/ @dongliuu @envyaims +/content/5_Plat/ @dongliuu +/solutions/platinum/ @dongliuu +/content/6_Advanced/ @dongliuu +/solutions/advanced/ @dongliuu /content/extraProblems.json @SansPapyrus683 @envyaims /content/team/ @SansPapyrus683 @ryanchou-dev diff --git a/content/1_General/Contests.mdx b/content/1_General/Contests.mdx index d1f1b29a2b..cbd1e704c3 100644 --- a/content/1_General/Contests.mdx +++ b/content/1_General/Contests.mdx @@ -7,7 +7,7 @@ description: 'Well-known programming contests and helpful tools for programming ## Frequent Contests -These websites hold contests that I frequently participate in. +These websites hold contests that I've often participated in. - [AtCoder](https://beta.atcoder.jp/contests/archive) - - Probably the highest quality - - Beginner / Regular Contests: 4 or 6 problems, ~100 min - - Grand Contests: 6 problems, 110 - 150 min - - Difficulty isn't always reasonable ... + - Beginner, Regular, and Grand contests, 100-180 min - [Codeforces](http://codeforces.com/problemset) - - Div 1-4: 5-6 problems (with some variations), 2 to 2.5 hrs -- [Topcoder](https://www.topcoder.com/my-dashboard/) - - Div 2, Div 1 - - 75 min coding, 15 min challenge - - Solutions only tested after contest! + - Div 1-4, 2-3 hrs - [DMOJ: Modern Online Judge](http://dmoj.ca/) - - at least one contest every month during school year - - practice implementation!! - - + - usually 3 hrs, can choose your start time within a window (like USACO) ## Other Websites - - misc ICPC contests + + 2-2.5 hrs - - Indonesian + + misc ICPC contests (5 hrs) - monthly Long, Lunchtime, Cookoff + monthly Starters -These platforms no longer actively hold contests, but might be worth a look. +These platforms no longer actively hold contests, but it might be worth looking +at past problems. see archive + + Two divisions. 75 min coding, 15 min challenge phases. Solutions only tested after contest. + ## Onsite Finals (Individual) -Let me know if there's something else I should try to qualify for! - recently updated - + + + + + + + **Manacher's Algorithm** functions similarly to the **Z-Algorithm**. It determines the longest palindrome centered at each character. @@ -356,25 +376,6 @@ int main() { - - - - - - If s[l, r] is a palindrome, then s[l+1, r-1] is as well. @@ -407,6 +408,12 @@ character palindrome must have been created from a palindrome of length $-1$ + + + + + + A trie is a tree-like data structure that stores strings. Each node is a string, and each edge is a character. The root is the empty string, and every node is represented by the characters along the path from the root to that node. @@ -481,11 +488,6 @@ int main() { - - - - - @@ -523,7 +525,7 @@ For example, when transitioning from $i$ to $i+1$ in $S$ there only are two choi 1. If $node$ does have an outgoing edge with letter $S_{i+1}$, then move down the edge. 2. Otherwise, follow the failure link of $S_i$ and transition to letter $S_{i+1}$ from there. -The image below depicts how the structure looks like for the words $[a, ag, c, caa, gag, gc]$. +The image below depicts how the structure looks like for the words $[a, ag, c, caa, gag, gc, gca]$.
![Trie](./Trie.png) diff --git a/solutions/gold/cses-1095.mdx b/solutions/gold/cses-1712.mdx similarity index 89% rename from solutions/gold/cses-1095.mdx rename to solutions/gold/cses-1712.mdx index 989edcd812..91e0bb0c57 100644 --- a/solutions/gold/cses-1095.mdx +++ b/solutions/gold/cses-1712.mdx @@ -7,7 +7,9 @@ author: Ryan Chou ## Explanation -[Fermat's Little Theorem](/gold/modular) tells us that $a^{p - 1} \equiv 1 \pmod{p}$, so we can calculate $a^{b^c \pmod{1e9 + 7 - 1}} \pmod{1e9+7}$ with modular exponentiation. +Let $M = 10^{9} + 7$. + +[Fermat's Little Theorem](/gold/modular) tells us that $a^{p - 1} \equiv 1 \pmod{p}$, so we can calculate $a^{b^c \pmod{M - 1}} \pmod{M}$ with modular exponentiation. ## Implementation diff --git a/solutions/platinum/cses-1191.mdx b/solutions/platinum/cses-1191.mdx index 2945f85f45..aed27800e2 100644 --- a/solutions/platinum/cses-1191.mdx +++ b/solutions/platinum/cses-1191.mdx @@ -2,127 +2,124 @@ id: cses-1191 source: CSES title: Cyclic Array -author: Chongtian Ma +author: Chongtian Ma, Rameez Parwez --- ## Explanation We can turn this into a graph problem, or more precisely, a tree. Let's add an edge from $u$ to $v$ if the maximum length of the subarray that starts at $v$ has to end at $u-1$, and so the next subarray must start at $u$. Remember the array is cyclic, so $u$ is not necessarily greater than $v$. This can be found using basic two pointers. We can iterate through the array with our left pointer and increment our right pointer if the sum between the two pointers is less than or equal to $k$. This will ensure that the subarray starting at the left pointer is as big as possible. -We can use binary lifting to find the start index of any next subarray in $\log(n)$ time. We can also track the number of elements between any two subarrays. - -Finally, we can binary search over the number of subarrays for the minimum. If we can use $x$ subarrays to cover the whole array, then we must also be able to use $x+1$ subarrays. +We can use binary lifting for each possible starting position to determine the number of jumps required to cover exactly $n$ elements. ## Implementation -**Time Complexity: $\mathcal O(n \log^2n)$** +**Time Complexity: $\mathcal O(n \log n)$** ```cpp -#include -using namespace std; -using ll = long long; +#include -const int MAXN = 2e5; -const int MAXL = 20; // approx maximum log base 2 of n +const int MAX_N = 2e5 + 1; +const int LOG = 20; /* * next[i][j] stores the start point of the next * 2^j'th subarray if we choose this subarray starting at i */ -array, MAXN> nxt; +int nxt[2 * MAX_N][LOG]; -/* - * len[i][j] stores the total amount of elements between - * subarray starting at i and the next 2^j'th subarray - */ -array, MAXN> len; +int arr[2 * MAX_N]; int main() { - ios::sync_with_stdio(false); - cin.tie(0); - int n; - ll k; - scanf("%d%lld", &n, &k); - vector a(n); - for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } - - ll sum = 0; - for (int i = 0; i < n; i++) { sum += a[i]; } - - // edge case: every element can go into one subarray - if (k >= sum) { - printf("%d", 1); - return 0; + long long k; + std::cin >> n >> k; + for (int i = 1; i <= n; i++) { + std::cin >> arr[i]; + arr[i + n] = arr[i]; } - // two pointers to find each subarray of the range [l,r) - sum = 0; - for (ll l = 0, r = 0; l < n; l++) { - while (sum + a[r % n] <= k) { - sum += a[r % n]; - r++; - } - - // initialize binary lifting arrays - nxt[l][0] = r % n; - len[l][0] = r - l; - - sum -= a[l]; + for (int i = 1, j = 1; i <= 2 * n; i++) { + arr[i] += arr[i - 1]; + while (arr[i] - arr[j] > k) { j++; } + nxt[i][0] = j; // farthest position reachable from i } - for (int j = 1; j < MAXL; j++) { - for (int i = 0; i < n; i++) { - nxt[i][j] = nxt[nxt[i][j - 1]][j - 1]; - // add lengths from the left and the right - len[i][j] = len[i][j - 1] + len[nxt[i][j - 1]][j - 1]; - } + // binary lifting transition + for (int j = 1; j < LOG; j++) { + for (int i = 1; i <= 2 * n; i++) { nxt[i][j] = nxt[nxt[i][j - 1]][j - 1]; } } - /* - * returns the number of elements between the subarray - * starting at x and the next y subarrays - */ - auto len_between = [&](int x, int y) -> ll { - ll total = 0; - for (int i = 0; i < MAXL; i++) { - if (y & (1 << i)) { - total += len[x][i]; - x = nxt[x][i]; - } - } + int res = n; + for (int i = n; i <= 2 * n; i++) { + int curr_res = 1; + int pos = i; - return total; - }; - - /* - * return true if there is a series of x subarrays - * that uses the whole array - */ - auto check = [&](int x) -> bool { - for (int i = 0; i < n; i++) { - if (len_between(i, x) >= n) { return true; } + // using binary lifting to simulate jumps and cover 'n' elements + for (int j = LOG - 1; j >= 0; j--) { + if (nxt[pos][j] > i - n) { + curr_res += (1 << j); + pos = nxt[pos][j]; + } } - return false; - }; - - /* - * binary search over the least amount of subarrays - * needed to cover the whole array - */ - int l = 0, r = n; - while (l < r - 1) { - int mid = l + (r - l) / 2; - if (check(mid)) { - r = mid; - } else l = mid; + res = std::min(res, curr_res); } - - printf("%d\n", r); + std::cout << res << '\n'; } ``` + + + + + +Submit the solution in PyPy3 to avoid TLE. + + + +```py +MAX_N = 200001 +LOG = 20 + +# next[i][j] stores the start point of the next +# 2^j'th subarray if we choose this subarray starting at i +nxt = [[0] * LOG for _ in range(2 * MAX_N)] + +n, k = map(int, input().split()) +arr = list(map(int, input().split())) + +arr = [0] + arr + arr + +j = 1 +for i in range(1, 2 * n + 1): + arr[i] += arr[i - 1] + while arr[i] - arr[j] > k: + j += 1 + + nxt[i][0] = j # farthest position reachable from i + +# binary lifting transition +for j in range(1, LOG): + for i in range(1, 2 * n + 1): + nxt[i][j] = nxt[nxt[i][j - 1]][j - 1] + +res = n +for i in range(n, 2 * n + 1): + curr_res = 1 + pos = i + + # using binary lifting to simulate jumps and cover 'n' elements + for j in range(LOG - 1, -1, -1): + if nxt[pos][j] > i - n: + curr_res += 1 << j + pos = nxt[pos][j] + + res = min(res, curr_res) + +print(res) +``` + + diff --git a/src/components/TopNavigationBar/TopNavigationBar.tsx b/src/components/TopNavigationBar/TopNavigationBar.tsx index 44d72378ad..ac54f1e8dc 100644 --- a/src/components/TopNavigationBar/TopNavigationBar.tsx +++ b/src/components/TopNavigationBar/TopNavigationBar.tsx @@ -138,9 +138,9 @@ export default function TopNavigationBar({ {!hidePromoBar && ( <> )}