├── Beginner Topics ├── README.md ├── [S1] Greed is good, sort of │ ├── [EP 1] Implementation.md │ ├── [EP 2] Greedy.md │ ├── [EP 3] Sorting.md │ ├── [EP 4] C++ STL.md │ ├── [EP 5] Frequency tables.md │ └── [~] Practice.md ├── [S2] Primal proficiency │ ├── [EP 1] Basic math.md │ ├── [EP 2] Primality, Factorization and Sieve.md │ ├── [EP 3] GCD and Totient function.md │ ├── [EP 4] Modular Arithmetic.md │ ├── [EP 5] Binary Exponentiation.md │ └── [~] Practice.md ├── [S3] 2P or not to 2P, No wait isn't this just bs │ ├── [EP 1] Prefix sums.md │ ├── [EP 2] Two pointers.md │ ├── [EP 3] Binary search.md │ ├── [EP 4] Ternary search.md │ └── [~] Practice.md ├── [S4] Boohoo~ It's dp time │ ├── [EP 0] Introduction to Dynamic Programming.md │ ├── [EP 1] Coin change.md │ ├── [EP 2] Maximum subarray sum.md │ ├── [EP 3] Knapsack.md │ ├── [EP 4] LCS & Edit distance.md │ ├── [EP 5] LIS.md │ ├── [EP 6] Grid DP.md │ ├── [EP 7] MCM style DP.md │ └── [~] Practice.md ├── [S5] Do you understand the graphity of this situation │ ├── [EP 0] Graph terminology and representation.md │ ├── [EP 1] Graph traversal │ │ ├── [Pt 1] DFS.md │ │ └── [Pt 2] BFS.md │ ├── [EP 2] Shortest paths │ │ ├── [Pt 1] Bellman-Ford.md │ │ ├── [Pt 2] Dijkstra's.md │ │ └── [Pt 3] Floyd-Warshall.md │ └── [EP 3] Spanning Trees │ │ ├── [Pt 1] Disjoint Set Union (Union Find).md │ │ ├── [Pt 2] Kruskal's MST.md │ │ └── [Pt 3] Prim's MST.md └── [S6] Boohoo~ It's dp time (again) │ └── to do.txt ├── C++ Tips and Tricks.md ├── CSES ├── Dynamic Programming │ ├── Array Description.cpp │ ├── Book Shop.cpp │ ├── Coin Combinations I.cpp │ ├── Coin Combinations II.cpp │ ├── Counting Numbers.cpp │ ├── Counting Tilings.cpp │ ├── Counting Towers.cpp │ ├── Dice Combinations.cpp │ ├── Edit Distance.cpp │ ├── Elevator Rides.cpp │ ├── Grid Paths.cpp │ ├── Increasing Subsequence.cpp │ ├── Minimizing Coins.cpp │ ├── Money Sums.cpp │ ├── Projects.cpp │ ├── Rectangle Cutting.cpp │ ├── Removal Game.cpp │ ├── Removing Digits.cpp │ └── Two Sets II.cpp ├── Graph Algorithms │ ├── Building Roads.cpp │ ├── Building Teams.cpp │ ├── Coin Collector.cpp │ ├── Counting Rooms.cpp │ ├── Course Schedule.cpp │ ├── Cycle Finding.cpp │ ├── Flight Discount.cpp │ ├── Flight Routes.cpp │ ├── Game Routes.cpp │ ├── Giant Pizza.cpp │ ├── Hamiltonian Flights.cpp │ ├── High Score.cpp │ ├── Investigation.cpp │ ├── Labyrinth.cpp │ ├── Longest Flight Route.cpp │ ├── Mail Delivery.cpp │ ├── Message Route.cpp │ ├── Monsters.cpp │ ├── Planets and Kingdoms.cpp │ ├── Road Construction.cpp │ ├── Road Reparation.cpp │ ├── Round Trip II.cpp │ ├── Round Trip.cpp │ ├── Shortest Routes I.cpp │ ├── Shortest Routes II.cpp │ └── Teleporters Path.cpp ├── README.md ├── Sorting and Searching │ ├── Apartments.cpp │ ├── Array Division.cpp │ ├── Collecting Numbers II.cpp │ ├── Collecting Numbers.cpp │ ├── Concert Tickets.cpp │ ├── Distinct Numbers.cpp │ ├── Factory Machines.cpp │ ├── Ferris Wheel.cpp │ ├── Josephus Problem I.cpp │ ├── Josephus Problem II.cpp │ ├── Maximum Subarray Sum II.cpp │ ├── Maximum Subarray Sum.cpp │ ├── Missing Coin Sum.cpp │ ├── Movie Festival II.cpp │ ├── Movie Festival.cpp │ ├── Nearest Smaller Values.cpp │ ├── Nested Ranges Check.cpp │ ├── Nested Ranges Count.cpp │ ├── Playlist.cpp │ ├── Reading Books.cpp │ ├── Restaurant Customers.cpp │ ├── Room Allocation.cpp │ ├── Sliding Cost.cpp │ ├── Sliding Median.cpp │ ├── Stick Lengths.cpp │ ├── Subarray Distinct Values.cpp │ ├── Subarray Divisibility.cpp │ ├── Subarray Sums I.cpp │ ├── Subarray Sums II.cpp │ ├── Sum of Four Values.cpp │ ├── Sum of Three Values.cpp │ ├── Sum of Two Values.cpp │ ├── Tasks and Deadlines.cpp │ ├── Towers.cpp │ └── Traffic Lights.cpp └── Tree Algorithms │ ├── Company Queries I.cpp │ ├── Company Queries II.cpp │ ├── Counting Paths.cpp │ ├── Distance Queries.cpp │ ├── Distinct Colors.cpp │ ├── Matching.cpp │ ├── Subordinates.cpp │ ├── Subtree Queries.cpp │ ├── Tree Diameter.cpp │ ├── Tree Distances I.cpp │ └── Tree Distances II.cpp ├── Competitve Programming Platforms.md ├── Complexity and Big-O Notation.md ├── Hello world.md ├── LICENSE ├── Macros and more.md ├── README.md ├── Sublime Text Setup.md └── 末 Snippets ├── 0-k knapsack.cpp ├── 2-SAT.cpp ├── BFS.cpp ├── BIT (Fenwick tree).cpp ├── BigInt.cpp ├── Binary exponentiation.cpp ├── Binary search.cpp ├── Closest pair of points.cpp ├── DSU.cpp ├── Dijkstra.cpp ├── Edge_t.cpp ├── Euler Circuit (directed).cpp ├── Euler Circuit (undirected).cpp ├── Extended Euclidean algorithm.cpp ├── FFT.cpp ├── Factorization.cpp ├── FileIO (freopen).cpp ├── Floyd Warshall.cpp ├── Fractions & Rationals.cpp ├── GP hash table (unordered map alternative).cpp ├── Gaussian elimination.cpp ├── KMP.cpp ├── LCA using Binary Lifting (O(nlogn) \ O(logn)).cpp ├── LCA using RMQ (O(n) \ O(1)).cpp ├── LIS.cpp ├── Lambda comparators.cpp ├── MST (Kruskal's algo).cpp ├── MST (Prim's algo).cpp ├── Manachers.cpp ├── Matrix (std::array).cpp ├── Matrix (std::vector).cpp ├── Mo's Algorithm ├── Mo's algorithm on trees (weighted edges).cpp ├── Mo's algorithm on trees (weighted nodes).cpp ├── Mo's algorithm with updates.cpp ├── Mo's algorithm.cpp ├── Query struct (Canonical).cpp └── Query struct (Hilbert ordering).cpp ├── ModInt.cpp ├── NTT.cpp ├── PBDS.cpp ├── Pollard rho.cpp ├── Random number generation.cpp ├── Remove duplicates.cpp ├── Run with larger stack size.cpp ├── SCC (Kosaraju's algo).cpp ├── SCC (Tarjan's algo).cpp ├── Segment trees ├── Iterative + Point updates (+ link to range updates).cpp ├── Recursive + Point updates.cpp ├── Recursive + Range updates (lazy prop).cpp ├── Recursive + persistent + point updates.cpp └── Recursive + persistent + range updates (lazy prop).cpp ├── Sieve of Eratosthenes.cpp ├── Sparse Table.cpp ├── Spread queue (using two stacks).cpp ├── String hashing (Rolling|Polynomial hash).cpp ├── Topsort.cpp ├── Treap struct (with lazy prop).cpp ├── Treap.cpp ├── Y combinator.cpp ├── Z algo.cpp ├── k_II(cpp20).h ├── k_II.h └── nCr.cpp /Beginner Topics/[S1] Greed is good, sort of/[EP 1] Implementation.md: -------------------------------------------------------------------------------- 1 | # Ad hoc/Implementation 2 | Implementation problems do not rely on the knowledge of any particular data structure or algorithm. There isn't really any way to learn this method except to practice problems. 3 | 4 |
5 | Problems 6 | 19 |
20 | 21 |
22 | 23 | **Note:** Sometimes the input may be large enough to cause an overflow. So remember to use `long long` (64-bit integer) instead of `int` (32-bit integer). It is safe to assume anything above 2∙109 overflows `int`, and anything above 2∙1018 overflows `long long int`. 24 | 25 | Problems mentioned in this episode, as well as subsequent ones, are only meant to serve as an introduction to a topic and are by no means enough to make you an expert at it (unless you are a genius). Be sure to practice more problems on the topics. You may go to [Problemset](https://codeforces.com/problemset) on Codeforces and filter by tag and/or rating to find appropriate problems. 26 | 27 | Also note that most codeforces problems have editorials (explanations of solutions). You can find them on the bottom right, usually labelled 'Tutorial'. Read them if you are stuck. 28 | -------------------------------------------------------------------------------- /Beginner Topics/[S1] Greed is good, sort of/[EP 2] Greedy.md: -------------------------------------------------------------------------------- 1 | # Greedy 2 | As the name suggests, a greedy approach is one where (greedily) picking the **best option** at every stage leads to the **best overall outcome**. 3 | 4 | **Reading material:** 5 | * [Hackerearth [B]](https://www.hackerearth.com/practice/algorithms/greedy/basics-of-greedy-algorithms/tutorial/) 6 | 7 |
8 | Problems 9 | 24 |
25 | -------------------------------------------------------------------------------- /Beginner Topics/[S1] Greed is good, sort of/[EP 5] Frequency tables.md: -------------------------------------------------------------------------------- 1 | # Frequency tables 2 | Consider an array of elements. The frequency of a particular element is the number of times it occurs in the array. Calculating the frequencies of each element can be very useful to solve certain kinds of problems. 3 | 4 | Frequency tables are usually built on arrays or vectors, but can also be built on maps (or hash maps) when the range of values is too large to fit in memory. 5 | The tradeoff is that maps have $\mathcal{O}(log n)$ lookup time, unlike arrays and vectors which have $\mathcal{O}(1)$ lookup time (Hash maps have $\mathcal{O}(1)$ lookup time *on average*, not in the worst case). 6 | 7 | **Reading material:** 8 | * [GFG [B]](https://www.geeksforgeeks.org/counting-frequencies-of-array-elements/) 9 | 10 |
11 | Problems 12 | 18 |
19 |
20 | 21 |
22 | Challenging problems 23 | 27 |
-------------------------------------------------------------------------------- /Beginner Topics/[S1] Greed is good, sort of/[~] Practice.md: -------------------------------------------------------------------------------- 1 | # Practice 2 | Mashups of topic relevant problems spanning a range of difficulties. 3 | 4 |
5 | Mashup 1 6 | 20 |
21 | 22 |
23 | Mashup 2 24 | 38 |
-------------------------------------------------------------------------------- /Beginner Topics/[S2] Primal proficiency/[EP 1] Basic math.md: -------------------------------------------------------------------------------- 1 | # Basic math 2 | 3 |
4 | Problems 5 | 17 |
-------------------------------------------------------------------------------- /Beginner Topics/[S2] Primal proficiency/[EP 2] Primality, Factorization and Sieve.md: -------------------------------------------------------------------------------- 1 | # Primality, Factorization and Sieve of Eratosthenes 2 | Efficient factorization and prime checking is a must know when it comes to competitive programming. This is the place to start for number theory. 3 | 4 | **Reading material:** 5 | * Introduction - *CPH Ch 21: Number theory,* pg [197](https://cses.fi/book/book.pdf#page=207) - [198](https://cses.fi/book/book.pdf#page=208) 6 | * Primality and Prime factorization - *CPH Ch 21,* pg [199](https://cses.fi/book/book.pdf#page=209) 7 | * Sieve of Eratosthenes 8 | * *CPH Ch 21,* pg [200](https://cses.fi/book/book.pdf#page=210) 9 | * [YouTube [V]](https://www.youtube.com/watch?v=pKvGYOnO9Ao) 10 | * [Visualization [B]](https://brilliant.org/wiki/sieve-of-eratosthenes/) 11 | * Prime factorization queries - [Tutorial [B]](https://www.geeksforgeeks.org/prime-factorization-using-sieve-olog-n-multiple-queries/) 12 | * Prime gap - [Article [B]](https://primes.utm.edu/notes/gaps.html) 13 | 14 |
15 | Problems 16 | 25 |
26 |
27 | 28 |
29 | Challenging problems 30 | 34 |
35 | -------------------------------------------------------------------------------- /Beginner Topics/[S2] Primal proficiency/[EP 3] GCD and Totient function.md: -------------------------------------------------------------------------------- 1 | # Euclidean GCD and Euler's Totient function 2 | You'll see a fair number of easy mathy problems whose solutions involve finding and using the Greatest Common Divisor (GCD) of some numbers. The Euler totient function is rarer, but it is still good to know. 3 | 4 | **Reading material:** 5 | * Euclid's algorithm 6 | * *CPH Ch 21,* pg [200](https://cses.fi/book/book.pdf#page=210) 7 | * [CP Algorithms](https://cp-algorithms.com/algebra/euclid-algorithm.html) 8 | * Euler's totient function 9 | * *CPH Ch 21,* pg [201](https://cses.fi/book/book.pdf#page=211) 10 | * [CP Algorithms](https://cp-algorithms.com/algebra/phi-function.html) 11 | * Topcoder article - [click](https://www.topcoder.com/thrive/articles/Prime%20Numbers,%20Factorization%20and%20Euler%20Function) 12 | 13 |
14 | Problems 15 | 24 |
25 |
26 |
27 | Challenging problems 28 | 36 |
37 |
38 | 39 | **Tip**: Use [std::gcd](https://en.cppreference.com/w/cpp/numeric/gcd) or **__gcd()** (a builtin function of the GCC compiler). 40 | -------------------------------------------------------------------------------- /Beginner Topics/[S2] Primal proficiency/[EP 5] Binary Exponentiation.md: -------------------------------------------------------------------------------- 1 | 2 | # Binary Exponentiation 3 | Binary exponentiation (also known as exponentiation by squaring) is a trick which allows you to calculate $a^n$ using only $\mathcal{O}(logn)$ multiplications (instead of $\mathcal{O}(n)$ multiplications). 4 | 5 | Of course, this also works under mod. This is sometimes referred to as Modular Exponentiation. 6 | 7 | **Reading material:** 8 | * [Errichto [V]](https://www.youtube.com/watch?v=L-Wzglnm4dM) 9 | * [CP Algorithms [B]](https://cp-algorithms.com/algebra/binary-exp.html) 10 | 11 |
12 | Problems 13 | 17 |
-------------------------------------------------------------------------------- /Beginner Topics/[S2] Primal proficiency/[~] Practice.md: -------------------------------------------------------------------------------- 1 | # Practice 2 | Mashups of topic relevant problems spanning a range of difficulties. 3 | 4 |
5 | Mashup 1 6 | 18 |
19 | 20 |
21 | Mashup 2 22 | 34 |
35 | 36 | -------------------------------------------------------------------------------- /Beginner Topics/[S3] 2P or not to 2P, No wait isn't this just bs/[EP 1] Prefix sums.md: -------------------------------------------------------------------------------- 1 | # Prefix sums 2 | Given an array $a$ of $n$ elements, prefix sums allow you to calculate the sum of any range of elements $[l, r]$ $1 \leq l \leq r \leq n$ in $\mathcal{O}(1)$ constant time (with $\mathcal{O}(n)$ pre-processing). 3 | 4 | The trick is to pre-calculate (to calculate once beforehand for multiple usages later) an array $\mathrm{prefix}$, of cumulative sums. For each $i$ from $1$ to $n$, $\mathrm{prefix}_i$ stores the sum $a_1 + a_2 + \ldots + a_i$. Then, the sum of elements in the range $[l, r]$ can be easily found out as $\mathrm{prefix}_r - \mathrm{prefix}_{l-1}$. 5 | 6 | **Reading material:** 7 | * [Peltorator [V]](https://codeforces.com/blog/entry/88474) (Use english subtitles) 8 | * [USACO [B]](https://usaco.guide/silver/prefix-sums?lang=cpp) 9 | * 2D prefix sums - [USACO [B]](https://usaco.guide/silver/more-prefix-sums?lang=cpp) 10 | * Range updates using prefix sums - [Codeforces [B]](https://codeforces.com/blog/entry/86420) 11 | 12 |
13 | Problems 14 | 26 |
27 |
28 | 29 | *This page uses math latex formatting. Download the [extension](https://chrome.google.com/webstore/detail/github-math-display/cgolaobglebjonjiblcjagnpmdmlgmda) to render it.* 30 | -------------------------------------------------------------------------------- /Beginner Topics/[S3] 2P or not to 2P, No wait isn't this just bs/[EP 2] Two pointers.md: -------------------------------------------------------------------------------- 1 | # Two pointers and sliding window 2 | The two pointer or 2p technique, is an op technique that has the power to reduce an $\mathcal{O}(n^2)$ algorithm to an $\mathcal{O}(n)$ one. 3 | 4 | **Reading material:** 5 | * Two pointers - [Quora [B]](https://tp-iiita.quora.com/The-Two-Pointer-Algorithm) & [CF EDU](https://codeforces.com/edu/course/2/lesson/9) 6 | * Sliding window - [GFG [B]](https://www.geeksforgeeks.org/window-sliding-technique/) 7 | * Sliding window applications - [Medium [B]](https://medium.com/techie-delight/top-problems-on-sliding-window-technique-8e63f1e2b1fa) 8 | 9 |
10 | Problems 11 | 23 |
24 | -------------------------------------------------------------------------------- /Beginner Topics/[S3] 2P or not to 2P, No wait isn't this just bs/[EP 4] Ternary search.md: -------------------------------------------------------------------------------- 1 | # Ternary Search 2 | Ternary Search is an extension of binary Search that allows you to locate the minima or maxima of a [unimodal function](https://en.wikipedia.org/wiki/Unimodality#:~:text=A%20common%20definition%20is%20as,Proving%20unimodality%20is%20often%20hard.). 3 | 4 | **Reading material:** 5 | * [CP Algorithms [B]](https://cp-algorithms.com/num_methods/ternary_search.html) - try reading this. Very detailed explanation. 6 | * [HackerEarth [B]](https://www.hackerearth.com/practice/algorithms/searching/ternary-search/tutorial/) 7 | 8 |
9 | Problems 10 | 17 |
18 | -------------------------------------------------------------------------------- /Beginner Topics/[S4] Boohoo~ It's dp time/[EP 0] Introduction to Dynamic Programming.md: -------------------------------------------------------------------------------- 1 | # Introduction to Dynamic Programming 2 | 3 |
4 | Dynamic programming (abbreviated DP), is an approach to solving problems through 'clever bruteforce'. It is a technique that combines the correctness of complete search and the efficiency of greedy algorithms. Dynamic programming can 5 | be applied if the problem can be divided into overlapping subproblems that can be solved independently. 6 | 7 | There are two common uses for dynamic programming: 8 | * **Finding an optimal solution**: You want to find a solution that is as large as possible or as small as possible. 9 | * **Counting the number of solutions**: You want to calculate the total number of possible solutions. 10 | 11 | If you're following this series, DP could be quite a jump in terms of difficulty and thinking of approaches to problems. Take your time to assimilate the contents of the following links/guides and understand what's going on. The internet has a lot more resources to explore if you're stuck. 12 | 13 | The links that follow are good to start with, but you will most probably have to revisit and re-read them multiple times as you struggle through the components that follow. 14 | 15 | **Reading material:** 16 | * [Errichto DP Lecture #1 [V]](https://www.youtube.com/watch?v=YBSt1jYwVfU) 17 | * [Topcoder [B]](https://www.topcoder.com/community/competitive-programming/tutorials/dynamic-programming-from-novice-to-advanced/) 18 | * [Hackerearth [B]](https://www.hackerearth.com/practice/algorithms/dynamic-programming/introduction-to-dynamic-programming-1/tutorial/) 19 | * [Blog [B]](https://skerritt.blog/dynamic-programming/) 20 | 21 |
22 | Problems 23 | 28 |
29 |
30 | 31 | **Note:** Solutions to [AtCoder DP contest](https://atcoder.jp/contests/dp/tasks) problems can be found [here](https://www.youtube.com/watch?v=FAQxdm0bTaw). -------------------------------------------------------------------------------- /Beginner Topics/[S4] Boohoo~ It's dp time/[EP 1] Coin change.md: -------------------------------------------------------------------------------- 1 | # Coin change 2 | 3 | **Reading material:** 4 | * [Errichto DP Lecture #2 [V]](https://www.youtube.com/watch?v=1mtvm2ubHCY) 5 | * *CPH Ch 7,* pg [65](https://cses.fi/book/book.pdf#page=75) - [70](https://cses.fi/book/book.pdf#page=80) 6 | * [Blog [B]](https://hackernoon.com/the-coin-change-problem-explained-ddd035a8f22f) 7 | 8 |
9 | Problems 10 | 16 |
17 |
18 | 19 | **Note:** Solutions to [CSES DP section](https://atcoder.jp/contests/dp/tasks) problems can be found [here](https://codeforces.com/blog/entry/70018). -------------------------------------------------------------------------------- /Beginner Topics/[S4] Boohoo~ It's dp time/[EP 2] Maximum subarray sum.md: -------------------------------------------------------------------------------- 1 | # Maximum sum subarray (Kadane's algorithm) 2 | 3 | **Reading material:** 4 | * [Medium [B]](https://medium.com/@rsinghal757/kadanes-algorithm-dynamic-programming-how-and-why-does-it-work-3fd8849ed73d) 5 | * *CPH Ch 2,* pg [21](https://cses.fi/book/book.pdf#page=31) - [23](https://cses.fi/book/book.pdf#page=33) 6 | 7 |
8 | Problems 9 | 15 |
-------------------------------------------------------------------------------- /Beginner Topics/[S4] Boohoo~ It's dp time/[EP 3] Knapsack.md: -------------------------------------------------------------------------------- 1 | # Knapsack 2 | 3 | **Reading material:** 4 | * [Algorithms Live [V]](https://www.youtube.com/watch?v=U4O3SwDamA4) 5 | * *CPH Ch 7,* pg [72](https://cses.fi/book/book.pdf#page=82) - [73](https://cses.fi/book/book.pdf#page=83) 6 | * [HackerEarth](https://www.hackerearth.com/practice/notes/the-knapsack-problem/) 7 | 8 |
9 | Problems 10 | 18 |
19 |
20 | 21 |
22 | Challenging problems 23 | 28 |
-------------------------------------------------------------------------------- /Beginner Topics/[S4] Boohoo~ It's dp time/[EP 4] LCS & Edit distance.md: -------------------------------------------------------------------------------- 1 | # Longest Common Subsequence & Edit distance 2 | 3 | **Reading material:** 4 | * Longest Common Subsequence 5 | * [Blog [B]](https://www.programiz.com/dsa/longest-common-subsequence) 6 | * [Errichto [V]](https://www.youtube.com/watch?v=KJWAQVmuFW0) 7 | * Edit distance 8 | * [Blog [B]](https://www.techiedelight.com/levenshtein-distance-edit-distance-problem/) 9 | * *CPH Ch 7,* pg [74](https://cses.fi/book/book.pdf#page=84) 10 | 11 | 12 |
13 | Problems 14 | 21 |
-------------------------------------------------------------------------------- /Beginner Topics/[S4] Boohoo~ It's dp time/[EP 5] LIS.md: -------------------------------------------------------------------------------- 1 | # Longest Increasing Subsequence 2 | The dp approach is $\mathcal{O}(n^2)$ and helps build intuition and understanding. However, since there exists methods to solve it in O(nlogn), often you will not be able to use this approach. 3 | 4 | **Reading material:** 5 | * $\mathcal{O}(n^2)$ 6 | * *CPH Ch 7,* pg [70](https://cses.fi/book/book.pdf#page=80) 7 | * $\mathcal{O}(nlogn)$ 8 | * [USACO guide](https://usaco.guide/gold/lis?lang=cpp) 9 | * [CP Algorithms](https://cp-algorithms.com/sequences/longest_increasing_subsequence.html) 10 | 11 |
12 | Problems 13 | 21 |
-------------------------------------------------------------------------------- /Beginner Topics/[S4] Boohoo~ It's dp time/[EP 6] Grid DP.md: -------------------------------------------------------------------------------- 1 | # Grid DP 2 | 3 | **Reading material:** 4 | * [Hackerearth [B]](https://www.hackerearth.com/practice/notes/dynamic-programming-problems-involving-grids/) 5 | * *CPH Ch 7,* pg [71](https://cses.fi/book/book.pdf#page=81) - [72](https://cses.fi/book/book.pdf#page=82) 6 | * [Errichto [V]](https://www.youtube.com/watch?v=NL12nchRoUE) 7 | 8 |
9 | Problems 10 | 15 |
-------------------------------------------------------------------------------- /Beginner Topics/[S4] Boohoo~ It's dp time/[EP 7] MCM style DP.md: -------------------------------------------------------------------------------- 1 | # Matrix Chain Multiplication style DP 2 | 3 | **Reading material:** 4 | * *Introduction to Algorithms, CLRS* pg [370](https://web.iiit.ac.in/~pratik.kamble/storage/Algorithms/Cormen_Algorithms_3rd.pdf#page=391) 5 | * [Blog [B]](https://www.techiedelight.com/matrix-chain-multiplication/) 6 | * [Video [V]](https://www.youtube.com/watch?v=prx1psByp7U) 7 | 8 |
9 | Problems 10 | 17 |
-------------------------------------------------------------------------------- /Beginner Topics/[S5] Do you understand the graphity of this situation/[EP 0] Graph terminology and representation.md: -------------------------------------------------------------------------------- 1 | # Introduction to Graph theory 2 | Many programming problems can be solved by modeling them as graph 3 | problems and using appropriate graph algorithms. A typical example of a graph 4 | is a network of roads and cities in a country. Sometimes though, the graph is 5 | hidden in the problem and it may be difficult to detect it. 6 | 7 | **Reading material:** 8 | * *CPH Ch 11,* pg [109](https://cses.fi/book/book.pdf#page=119) - [116](https://cses.fi/book/book.pdf#page=126) 9 | * [Hackerearth [B]](https://www.hackerearth.com/practice/algorithms/graphs/graph-representation/tutorial/) 10 | * A [collection](https://codeforces.com/blog/entry/16221) of several graph algorithms 11 | * Basic Problems - [E-Olymp Graph representation](https://www.e-olymp.com/en/contests/9060) -------------------------------------------------------------------------------- /Beginner Topics/[S5] Do you understand the graphity of this situation/[EP 1] Graph traversal/[Pt 1] DFS.md: -------------------------------------------------------------------------------- 1 | ## Depth First Search (DFS) 2 | 3 | **Reading material:** 4 | * *CPH Ch 12,* pg [117](https://cses.fi/book/book.pdf#page=127) - [118](https://cses.fi/book/book.pdf#page=128) 5 | * [Hackerearth [B]](https://www.hackerearth.com/practice/algorithms/graphs/depth-first-search/tutorial/) 6 | * [CP Algorithms](https://cp-algorithms.com/graph/depth-first-search.html) 7 | * Basic Problems - [E-Olymp DFS](https://www.e-olymp.com/en/contests/9116) 8 | * DFS Applications 9 | * *CPH Ch 12,* pg [121](https://cses.fi/book/book.pdf#page=131) - [122](https://cses.fi/book/book.pdf#page=132) 10 | * [-is-this-fft-'s legendary blog on CF](https://codeforces.com/blog/entry/68138) (for later reading) 11 | 12 |
13 | Problems 14 | 26 |
-------------------------------------------------------------------------------- /Beginner Topics/[S5] Do you understand the graphity of this situation/[EP 1] Graph traversal/[Pt 2] BFS.md: -------------------------------------------------------------------------------- 1 | ## Breadth First Search (BFS) 2 | 3 | **Reading material:** 4 | * *CPH Ch 12,* pg [119](https://cses.fi/book/book.pdf#page=129) - [120](https://cses.fi/book/book.pdf#page=130) 5 | * [Hackerearth [B]](https://www.hackerearth.com/practice/algorithms/graphs/breadth-first-search/tutorial/) 6 | * [CP Algorithms](https://cp-algorithms.com/graph/breadth-first-search.html) 7 | * Basic Problems - [E-Olymp BFS](https://www.e-olymp.com/en/contests/9208) 8 | 9 |
10 | Problems 11 | 21 |
22 |
23 | 24 | **See also:** [0-1 BFS](https://cp-algorithms.com/graph/01_bfs.html) | [Alt](https://codeforces.com/blog/entry/22276) 25 | 26 |
27 | 0-1 BFS Problems 28 | 33 |
-------------------------------------------------------------------------------- /Beginner Topics/[S5] Do you understand the graphity of this situation/[EP 2] Shortest paths/[Pt 1] Bellman-Ford.md: -------------------------------------------------------------------------------- 1 | # Bellman-Ford Algorithm 2 | 3 | **Reading material:** 4 | * *CPH Ch 13,* pg [123](https://cses.fi/book/book.pdf#page=133) - [126](https://cses.fi/book/book.pdf#page=136) 5 | * [CP Algorithms](https://cp-algorithms.com/graph/bellman_ford.html) 6 | 7 |
8 | Problems 9 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /Beginner Topics/[S5] Do you understand the graphity of this situation/[EP 2] Shortest paths/[Pt 2] Dijkstra's.md: -------------------------------------------------------------------------------- 1 | # Dijkstra's Algorithm 2 | 3 | **Reading material:** 4 | * *CPH Ch 13,* pg [126](https://cses.fi/book/book.pdf#page=136) - [129](https://cses.fi/book/book.pdf#page=139) 5 | * CP Algorithms 6 | * [Dijkstra Algorithm](https://cp-algorithms.com/graph/dijkstra.html) 7 | * [Dijkstra on sparse graphs](https://cp-algorithms.com/graph/dijkstra_sparse.html) 8 | 9 |
10 | Problems 11 | 23 |
-------------------------------------------------------------------------------- /Beginner Topics/[S5] Do you understand the graphity of this situation/[EP 2] Shortest paths/[Pt 3] Floyd-Warshall.md: -------------------------------------------------------------------------------- 1 | # Floyd-Warshall Algorithm 2 | 3 | **Reading material:** 4 | * *CPH Ch 13,* pg [129](https://cses.fi/book/book.pdf#page=139) - [131](https://cses.fi/book/book.pdf#page=141) 5 | * [CP Algorithms](https://cp-algorithms.com/graph/all-pair-shortest-path-floyd-warshall.html) 6 | 7 |
8 | Problems 9 | 16 |
-------------------------------------------------------------------------------- /Beginner Topics/[S5] Do you understand the graphity of this situation/[EP 3] Spanning Trees/[Pt 1] Disjoint Set Union (Union Find).md: -------------------------------------------------------------------------------- 1 | # Disjoint Set Union or Union Find 2 | 3 | **Reading material:** 4 | * *CPH Ch 15,* pg [145](https://cses.fi/book/book.pdf#page=155) - [147](https://cses.fi/book/book.pdf#page=157) 5 | * [CS Academy [B]](https://csacademy.com/lesson/disjoint_data_sets/) 6 | * [CP Algorithms](https://cp-algorithms.com/data_structures/disjoint_set_union.html) 7 | * CF EDU on [Disjoint Set Union](https://codeforces.com/edu/course/2/lesson/7) 8 | 9 |
10 | Problems 11 | 22 |
-------------------------------------------------------------------------------- /Beginner Topics/[S5] Do you understand the graphity of this situation/[EP 3] Spanning Trees/[Pt 2] Kruskal's MST.md: -------------------------------------------------------------------------------- 1 | # Kruskal's Algorithm 2 | 3 | **Reading material:** 4 | * *CPH Ch 15,* pg [141](https://cses.fi/book/book.pdf#page=151) - [145](https://cses.fi/book/book.pdf#page=155) 5 | * CP Algorithms 6 | * [Kruskal's Algorithm](https://cp-algorithms.com/graph/mst_kruskal.html) 7 | * [Kruskal with DSU](https://cp-algorithms.com/graph/mst_kruskal_with_dsu.html) 8 | 9 |
10 | Problems 11 | 21 |
-------------------------------------------------------------------------------- /Beginner Topics/[S5] Do you understand the graphity of this situation/[EP 3] Spanning Trees/[Pt 3] Prim's MST.md: -------------------------------------------------------------------------------- 1 | # Prim's Algorithm 2 | 3 | **Reading material:** 4 | * *CPH Ch 15,* pg [147](https://cses.fi/book/book.pdf#page=157) - [148](https://cses.fi/book/book.pdf#page=158) 5 | * [CP Algorithms](https://cp-algorithms.com/graph/mst_prim.html) 6 | 7 |
8 | Problems 9 | 19 |
20 | -------------------------------------------------------------------------------- /Beginner Topics/[S6] Boohoo~ It's dp time (again)/to do.txt: -------------------------------------------------------------------------------- 1 | Bitmask dp 2 | Tree dp 3 | SOS dp 4 | Matrix Exponentiation 5 | 6 | * [Bitmasks](https://www.hackerearth.com/practice/algorithms/dynamic-programming/bit-masking/tutorial/) 7 | * [Sum over subsets (SoS)](https://codeforces.com/blog/entry/45223) 8 | * [DP on trees](https://codeforces.com/blog/entry/20935) 9 | 10 | ## Matrix exponentiation 11 | * [Modular arithmetic, combinatorics and exponentiation](https://codeforces.com/blog/entry/78873) 12 | 13 | https://codeforces.com/blog/entry/93914 14 | 15 | [Tutorial](http://zobayer.blogspot.com/2010/11/matrix-exponentiation.html)\ 16 | [Another good read](https://codeforces.com/blog/entry/67776)\ 17 | [Errichto video](https://www.youtube.com/watch?v=eMXNWcbw75E_)\ 18 | [Optimized to O(k^2 logN) using Cayley Hamilton theorem](https://discuss.codechef.com/t/linear-recurrence-using-cayley-hamilton-theorem/6776) 19 | 20 | #### Problems 21 | * [Spoj FIBOFAST](https://www.spoj.com/problems/FIBOFAST/) 22 | * [SPOJ Mpow](https://www.spoj.com/problems/MPOW/) 23 | * [SPOJ FiboSum](https://www.spoj.com/problems/FIBOSUM/cstart=10) 24 | * [Codeforces 185 A](https://codeforces.com/contest/185/problem/A) 25 | * [Codeforces 166 E](https://codeforces.com/problemset/problem/166/E) 26 | * [Codeforces 1117 D](https://codeforces.com/problemset/problem/1117/D) 27 | * [Mat expo training contest (Errichto)](https://codeforces.com/gym/102644) -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Array Description.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.12.2020 18:26:28 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 1e5 + 5; 18 | const int M = 100 + 5; 19 | int64_t dp[N][M], a[N]; 20 | 21 | int main() { 22 | cin.tie(nullptr)->sync_with_stdio(false); 23 | int i, j, n, m; 24 | cin >> n >> m; 25 | for(i = 0; i < n; i++) 26 | cin >> a[i]; 27 | 28 | if(!a[0]) fill(dp[0]+1, dp[0]+m+1, 1); 29 | else dp[0][a[0]] = 1; 30 | 31 | for(i = 1; i < n; i++) { 32 | if(a[i]) { 33 | dp[i][a[i]] = dp[i-1][a[i]-1] + dp[i-1][a[i]] + dp[i-1][a[i]+1]; 34 | dp[i][a[i]] %= MOD; 35 | } else { 36 | for(j = 1; j <= m; j++) { 37 | dp[i][j] = dp[i-1][j-1] + dp[i-1][j] + dp[i-1][j+1]; 38 | dp[i][j] %= MOD; 39 | } 40 | } 41 | } cout << accumulate(dp[n-1], dp[n-1]+m+1, 0ll) % MOD; 42 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Book Shop.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.12.2020 18:21:37 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t DESPACITO = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 2e5 + 5; 20 | int dp[N], cost[N], val[N]; 21 | 22 | int main() { 23 | cin.tie(nullptr)->sync_with_stdio(false); 24 | int i, j, n, S; 25 | cin >> n >> S; 26 | for(i = 0; i < n; i++) 27 | cin >> cost[i]; 28 | for(i = 0; i < n; i++) 29 | cin >> val[i]; 30 | 31 | for(i = 0; i < n; i++) 32 | for(j = S; j >= cost[i]; --j) 33 | chmax(dp[j], dp[j-cost[i]] + val[i]); 34 | 35 | cout << *max_element(dp, dp+S+1); 36 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Coin Combinations I.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.12.2020 17:31:52 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 1e6 + 5; 18 | int c[N], dp[N]; 19 | 20 | int main() { 21 | cin.tie(nullptr)->sync_with_stdio(false); 22 | int i, j, n, S; 23 | cin >> n >> S; 24 | for(i = 0; i < n; i++) 25 | cin >> c[i]; 26 | sort(c, c+n); 27 | 28 | dp[0] = 1; 29 | for(i = 0; i < S; i++) 30 | for(j = 0; j < n; j++) 31 | if(i + c[j] <= S) 32 | (dp[i+c[j]] += dp[i]) %= MOD; 33 | 34 | cout << dp[S]; 35 | } // ~W 36 | 37 | 38 | /* Recursive~ */ 39 | 40 | /** 41 | 🍪 the_hyp0cr1t3 42 | 🍪 12.01.2021 15:45:41 43 | **/ 44 | #ifdef W 45 | #include "k_II.h" 46 | #else 47 | #include 48 | using namespace std; 49 | #endif 50 | #define pb emplace_back 51 | #define all(x) x.begin(), x.end() 52 | #define sz(x) static_cast(x.size()) 53 | 54 | const int64_t DESPACITO = 2e18; 55 | const int INF = 2e9, MOD = 1e9+7; 56 | const int N = 100 + 5; 57 | const int M = 1e6 + 5; 58 | int weights[N], cache[M]; 59 | 60 | int dp(int S) { 61 | if(S < 0) return 0; 62 | int& ans = cache[S]; 63 | if(~ans) return ans; 64 | ans = 0; 65 | for(int i = 0; weights[i] <= S; i++) { 66 | ans += dp(S - weights[i]); 67 | if(ans >= MOD) ans -= MOD; 68 | } return ans; 69 | } 70 | 71 | int main() { 72 | cin.tie(nullptr)->sync_with_stdio(false); 73 | int i, n, S; 74 | cin >> n >> S; 75 | for(i = 0; i < n; i++) 76 | cin >> weights[i]; 77 | sort(weights, weights + n); 78 | weights[n] = INF; 79 | memset(cache, -1, sizeof(cache)); 80 | cache[0] = 1; 81 | cout << dp(S); 82 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Coin Combinations II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 17:06:56 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 101; 18 | const int M = 1e6 + 5; 19 | int dp[N][M]; 20 | 21 | int main() { 22 | cin.tie(nullptr)->sync_with_stdio(false); 23 | int i, j, n, k; 24 | cin >> n >> k; 25 | vector a(n); 26 | for(auto& x: a) cin >> x; 27 | 28 | dp[0][0] = 1; 29 | for(i = 1; i <= n; i++) { 30 | for(j = 0; j <= k; j++) { 31 | dp[i][j] = dp[i-1][j]; 32 | int remain = j - a[i-1]; 33 | if(remain >= 0) { 34 | dp[i][j] += dp[i][remain]; 35 | if(dp[i][j] >= MOD) 36 | dp[i][j] -= MOD; 37 | } 38 | } 39 | } 40 | 41 | cout << dp[n][k]; 42 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Counting Numbers.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 02.02.2021 23:55:33 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | int64_t dp[20][2][10]; 19 | 20 | int main() { 21 | cin.tie(nullptr)->sync_with_stdio(false); 22 | int64_t A, B; 23 | cin >> A >> B; 24 | 25 | auto go = [](int64_t n) { 26 | stringstream ss; string s; 27 | ss << n; ss >> s; reverse(all(s)); 28 | int64_t ans = 0; 29 | memset(dp, 0, sizeof(dp)); 30 | dp[0][0][0] = dp[0][1][0] = dp[1][0][0] = dp[1][1][0] = 1; 31 | for(int len = 1; len <= sz(s); len++) { 32 | for(int j = 0; j < 10; j++) { 33 | for(int k = 0; k < 10; k++) { 34 | dp[len][0][j] += j ^ k? dp[len-1][0][k] : 0; 35 | if(j == s[len-1]-'0') { 36 | dp[len][1][j] += k ^ j? dp[len-1][1][k] : 0; 37 | } else if(j < s[len-1]-'0') { 38 | dp[len][1][j] += j ^ k? dp[len-1][0][k] : 0; 39 | } 40 | } if(len == 1 or j) ans += dp[len][len == sz(s)][j]; 41 | } 42 | } return ans; 43 | }; 44 | 45 | cout << go(B) - (A > 0? go(A - 1) : 0); 46 | 47 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Dice Combinations.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.12.2020 17:26:32 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 1e6 + 10; 18 | int dp[N][6]; 19 | 20 | int main() { 21 | cin.tie(nullptr)->sync_with_stdio(false); 22 | int i, j, k, n; 23 | cin >> n; 24 | 25 | dp[0][0] = 1; 26 | for(i = 0; i < n; i++) 27 | for(j = 0; j < 6; j++) 28 | for(k = 0; k < 6; k++) 29 | (dp[i+k+1][k] += dp[i][j]) %= MOD; 30 | 31 | int ans = 0; 32 | for(j = 0; j < 6; j++) 33 | (ans += dp[n][j]) %= MOD; 34 | cout << ans; 35 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Edit Distance.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.12.2020 18:37:28 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t DESPACITO = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 5000 + 5; 20 | int dp[N][N]; 21 | 22 | int main() { 23 | cin.tie(nullptr)->sync_with_stdio(false); 24 | int i, j, n, m; string s, t; 25 | cin >> s >> t; n = sz(s); m = sz(t); 26 | 27 | for(i = 0; i <= n; i++) 28 | for(j = 0; j <= m; j++) 29 | dp[i][j] = INF; 30 | dp[0][0] = 0; 31 | 32 | for(i = 0; i <= n; i++) { 33 | for(j = 0; j <= m; j++) { 34 | if(i) chmin(dp[i][j], dp[i-1][j] + 1); 35 | if(j) chmin(dp[i][j], dp[i][j-1] + 1); 36 | if(i and j) chmin(dp[i][j], dp[i-1][j-1] + (s[i-1] != t[j-1])); 37 | } 38 | } 39 | 40 | cout << dp[n][m]; 41 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Elevator Rides.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 02.02.2021 23:25:43 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t DESPACITO = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 20; 20 | int a[N]; 21 | array, 1 << N> dp; 22 | 23 | int main() { 24 | cin.tie(nullptr)->sync_with_stdio(false); 25 | int i, n, S; 26 | cin >> n >> S; 27 | for(i = 0; i < n; i++) 28 | cin >> a[i]; 29 | 30 | dp.fill({INF, INF}); dp[0] = {1, 0}; 31 | for(int msk = 1; msk < 1<>i&1) { 34 | auto cand = dp[msk ^ 1< S) 37 | cand[0]++, cand[1] = a[i]; 38 | chmin(dp[msk], cand); 39 | } 40 | } 41 | } cout << dp[(1< 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 1000 + 5; 18 | int dp[N][N]; 19 | 20 | int main() { 21 | cin.tie(nullptr)->sync_with_stdio(false); 22 | int i, j, n; 23 | cin >> n; 24 | vector a(n); 25 | for(auto& x: a) cin >> x; 26 | 27 | dp[1][0] = a[0][0] == '.'; 28 | for(i = 1; i <= n; i++) 29 | for(j = 1; j <= n; j++) 30 | if(a[i-1][j-1] == '.') dp[i][j] = (dp[i-1][j] + dp[i][j-1]) % MOD; 31 | 32 | cout << dp[n][n]; 33 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Increasing Subsequence.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 17:18:28 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; 22 | cin >> n; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | 26 | auto LIS = [&] (const vector& v) { 27 | vector lis; lis.reserve(n); 28 | for(int z = 0; z < n; z++) { 29 | // v[A] <= v[B] for strictly incr, v[A] < v[B] otherwise 30 | auto it = upper_bound(all(lis), z, [&](const auto& A, const auto& B) { 31 | return v[A] <= v[B]; 32 | }); 33 | int idx = int(it - lis.begin()); 34 | if(it == lis.end()) lis.pb(z); 35 | else lis[idx] = z; 36 | } return sz(lis); 37 | }; 38 | 39 | cout << LIS(a); 40 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Minimizing Coins.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.12.2020 17:31:52 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t DESPACITO = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 1e6 + 5; 20 | int c[N], dp[N]; 21 | 22 | int main() { 23 | cin.tie(nullptr)->sync_with_stdio(false); 24 | int i, j, n, S; 25 | cin >> n >> S; 26 | for(i = 0; i < n; i++) 27 | cin >> c[i]; 28 | sort(c, c+n); 29 | 30 | for(i = 0; i <= S; i++) 31 | dp[i] = INF; 32 | dp[0] = 0; 33 | 34 | for(i = 0; i <= S; i++) 35 | for(j = 0; j < n; j++) 36 | if(i + c[j] <= S) 37 | chmin(dp[i+c[j]], dp[i] + 1); 38 | 39 | cout << (dp[S] == INF? -1 : dp[S]); 40 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Money Sums.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.12.2020 18:50:14 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 1e5 + 5; 18 | int dp[N+1]; 19 | 20 | int main() { 21 | cin.tie(nullptr)->sync_with_stdio(false); 22 | int i, j, n; 23 | cin >> n; 24 | for(dp[i = 0] = 1; i < n; i++) { 25 | int x; cin >> x; 26 | for(j = N-1; j >= x; --j) 27 | if(dp[j-x]) dp[j] = true; 28 | } 29 | 30 | cout << accumulate(dp+1, dp+N, 0) << '\n'; 31 | for(i = 1; i < N; i++) 32 | if(dp[i]) cout << i << ' '; 33 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Projects.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 10.11.2020 11:41:01 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t DESPACITO = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 2e5 + 5; 20 | 21 | int main() { 22 | cin.tie(nullptr)->sync_with_stdio(false); 23 | int i, j, n, m = 1, cur = 0; 24 | cin >> n; 25 | map hsh; 26 | vector> a(n); 27 | for(i = 0; i < n; i++) { 28 | for(j = 0; j < 3; j++) 29 | cin >> a[i][j]; 30 | hsh[a[i][0]]; hsh[a[i][1]]; 31 | } 32 | 33 | for(auto& [k, v]: hsh) 34 | v = m++; 35 | for(auto& [l, r, c]: a) 36 | l = hsh[l], r = hsh[r]; 37 | sort(all(a)); 38 | 39 | vector dp(m+1); 40 | for(auto& [l, r, c]: a) { 41 | while(cur < l) chmax(dp[cur+1], dp[cur]), ++cur; 42 | chmax(dp[r], dp[l-1] + c); 43 | } while(cur < m) chmax(dp[cur+1], dp[cur]), ++cur; 44 | 45 | cout << dp[m] << '\n'; 46 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Rectangle Cutting.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.12.2020 18:44:16 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t DESPACITO = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 500 + 5; 20 | int dp[N][N]; 21 | 22 | int main() { 23 | cin.tie(nullptr)->sync_with_stdio(false); 24 | int i, j, k, a, b; 25 | cin >> a >> b; 26 | 27 | for(i = 1; i <= a; i++) { 28 | for(j = 1; j <= b; j++) { 29 | if(i == j) continue; 30 | dp[i][j] = INF; 31 | for(k = 1; k < i; k++) 32 | chmin(dp[i][j], dp[k][j] + dp[i-k][j] + 1); 33 | for(k = 1; k < j; k++) 34 | chmin(dp[i][j], dp[i][k] + dp[i][j-k] + 1); 35 | } 36 | } cout << dp[a][b]; 37 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Removal Game.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 31.08.2020 10:14:30 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #define aylmao cin.tie(nullptr)->sync_with_stdio(false); 11 | #endif 12 | #define endl '\n' 13 | #define pb emplace_back 14 | // #define int long long 15 | #define sz(x) (int)((x).size()) 16 | #define all(x) x.begin(), x.end() 17 | #define Luv(...) [&](auto&& u, auto&& v) { return __VA_ARGS__; } 18 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 19 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 20 | 21 | using ll = long long; 22 | using pii = pair; 23 | const ll DESPACITO = 2e18; 24 | const int INF = 2e9, MOD = 1e9+7; 25 | 26 | const int N = 2e5+5; 27 | int a[N]; 28 | 29 | int32_t main() { 30 | aylmao 31 | int i, n, cur = 1; ll ans = 0; 32 | cin >> n; 33 | for(i = 0; i < n; i++) 34 | cin >> a[i]; 35 | deque v; 36 | for(i = 0; i < n; i++) { 37 | v.push_back(a[i]); 38 | while(sz(v) > 2) { 39 | ll x = v[sz(v)-3]; 40 | ll y = v[sz(v)-2]; 41 | ll z = v[sz(v)-1]; 42 | if(x > y or y < z) break; 43 | v.pop_back(); v.pop_back(); v.pop_back(); 44 | v.push_back(x+z-y); 45 | } 46 | } 47 | while(!v.empty()) { 48 | ans += max(v.front(), v.back()) * cur; 49 | if(v.front() > v.back()) v.pop_front(); 50 | else v.pop_back(); 51 | cur = -cur; 52 | } 53 | cout << (accumulate(a, a+n, 0ll) + ans >> 1); 54 | return 0; 55 | } -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Removing Digits.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.12.2020 18:05:04 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t DESPACITO = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 1e6 + 5; 20 | int dp[N]; 21 | 22 | int main() { 23 | cin.tie(nullptr)->sync_with_stdio(false); 24 | int i, n; 25 | cin >> n; 26 | 27 | fill(dp, dp+n, INF); 28 | for(i = n; i; --i) { 29 | int x = i; 30 | while(x) chmin(dp[i-x%10], dp[i] + 1), x /= 10; 31 | } cout << dp[0]; 32 | } // ~W -------------------------------------------------------------------------------- /CSES/Dynamic Programming/Two Sets II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.12.2020 19:40:29 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define sz(x) int(x.size()) 13 | #define all(x) x.begin(), x.end() 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | int dp[N]; 19 | 20 | int main() { 21 | cin.tie(nullptr)->sync_with_stdio(false); 22 | int i, j, n; 23 | cin >> n; 24 | int sum = n * (n+1) >> 1; 25 | 26 | if(sum & 1) return cout << 0, 0; 27 | sum >>= 1; 28 | 29 | dp[0] = 1; 30 | for(i = 1; i <= n; i++) 31 | for(j = sum; j >= i; --j) 32 | (dp[j] += dp[j-i]) %= MOD; 33 | 34 | cout << (500000004ll * dp[sum] % MOD); 35 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Building Roads.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 17.05.2021 22:26:38 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t k_II = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, m; 22 | cin >> n >> m; 23 | 24 | vector par(n, -1); 25 | auto get_par = [&par](int A) { 26 | while(par[A] >= 0) { 27 | if(par[par[A]] >= 0) par[A] = par[par[A]]; 28 | A = par[A]; 29 | } return A; 30 | }; 31 | 32 | auto merge = [&get_par, &par](int A, int B) { 33 | A = get_par(A); B = get_par(B); 34 | if(A == B) return false; 35 | if(-par[A] < -par[B]) swap(A, B); 36 | par[A] += par[B]; par[B] = A; 37 | return true; 38 | }; 39 | 40 | while(m--) { 41 | int u, v; cin >> u >> v; 42 | merge(--u, --v); 43 | } 44 | 45 | int x = -1; 46 | vector> ans; 47 | for(i = 0; i < n; i++) { 48 | if(par[i] < 0) { 49 | if(~x) ans.pb(x, i); 50 | x = i; 51 | } 52 | } 53 | 54 | cout << sz(ans) << '\n'; 55 | for(auto& [x, y]: ans) 56 | cout << x+1 << ' ' << y+1 << '\n'; 57 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Building Teams.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 17.05.2021 22:46:57 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t k_II = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, m; 22 | cin >> n >> m; 23 | 24 | vector par(n, -1), val(n); 25 | auto get_par = [&par, &val](int A) { 26 | int v = 0; 27 | while(par[A] >= 0) { 28 | if(par[par[A]] >= 0) { 29 | val[A] ^= val[par[A]]; 30 | par[A] = par[par[A]]; 31 | } v ^= val[A], A = par[A]; 32 | } return pair{ A, v ^ val[A] }; 33 | }; 34 | 35 | auto merge = [&get_par, &par, &val](int _A, int _B) { 36 | auto[A, a] = get_par(_A); 37 | auto [B, b] = get_par(_B); 38 | if(A == B) return a ^ b; 39 | if(-par[A] < -par[B]) swap(A, B); 40 | par[A] += par[B]; par[B] = A; 41 | val[B] = a ^ b ^ 1; 42 | return 1; 43 | }; 44 | 45 | while(m--) { 46 | int u, v; cin >> u >> v; 47 | if(!merge(--u, --v)) 48 | return cout << "IMPOSSIBLE" << '\n', 0; 49 | } 50 | 51 | for(i = 0; i < n; i++) 52 | cout << get_par(i).second + 1 << " \n"[i == n-1]; 53 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Counting Rooms.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 17.05.2021 21:55:07 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | const array dx{1, 0, -1, 0}; 25 | const array dy{0, 1, 0, -1}; 26 | 27 | const int64_t k_II = 2e18; 28 | const int INF = 2e9, MOD = 1e9+7; 29 | const int N = 2e5 + 5; 30 | 31 | int main() { 32 | cin.tie(nullptr)->sync_with_stdio(false); 33 | int i, j, n, m, ans = 0; 34 | cin >> n >> m; 35 | vector a(n); 36 | for(auto& x: a) cin >> x; 37 | 38 | auto valid = [&](int x, int y) { 39 | return 0 <= x and x < n and 0 <= y and y < m and a[x][y] == '.'; 40 | }; 41 | 42 | vector> vis(n, vector(m)); 43 | auto dfs = Y([&](auto dfs, int x, int y) -> void { 44 | vis[x][y] = 1; 45 | for(int z = 0; z < 4; z++) { 46 | int nx = x + dx[z]; 47 | int ny = y + dy[z]; 48 | if(valid(nx, ny) and !vis[nx][ny]) 49 | dfs(nx, ny); 50 | } 51 | }); 52 | 53 | for(i = 0; i < n; i++) 54 | for(j = 0; j < m; j++) 55 | if(!vis[i][j] and a[i][j] == '.') 56 | dfs(i, j), ans++; 57 | 58 | cout << ans << endl; 59 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Course Schedule.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 19.05.2021 18:22:59 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t k_II = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, m; 22 | cin >> n >> m; 23 | vector> g(n); 24 | vector indeg(n); 25 | for(i = 0; i < m; i++) { 26 | int u, v; cin >> u >> v; u--, v--; 27 | g[u].pb(v); indeg[v]++; 28 | } 29 | 30 | // topsort 31 | queue q; 32 | vector order; order.reserve(n); 33 | for(i = 0; i < n; i++) 34 | if(!indeg[i]) q.push(i); 35 | while(!q.empty()) { 36 | auto v = q.front(); q.pop(); 37 | order.pb(v); 38 | for(auto& x: g[v]) 39 | if(!--indeg[x]) q.push(x); 40 | } 41 | 42 | if(sz(order) < n) 43 | return cout << "IMPOSSIBLE" << '\n', 0; 44 | 45 | for(auto& x: order) 46 | cout << x+1 << ' '; 47 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Cycle Finding.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 18.05.2021 11:18:52 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | struct edge_t { 18 | int u{-1}, v{-1}; int64_t w{0}; 19 | edge_t() = default; 20 | edge_t(int u, int v, int64_t w = 0) : u(u), v(v), w(w) {} 21 | bool operator<(const edge_t& other) { return w < other.w; } 22 | friend ostream& operator<<(ostream& os, const edge_t& e) { os << e.u << ' ' << e.v << ' ' << e.w; return os; } 23 | }; 24 | 25 | const int64_t k_II = 2e18; 26 | const int INF = 2e9, MOD = 1e9+7; 27 | const int N = 2e5 + 5; 28 | 29 | int main() { 30 | cin.tie(nullptr)->sync_with_stdio(false); 31 | int i, n, m, x; 32 | cin >> n >> m; 33 | vector edges(m); 34 | for(auto& e: edges) { 35 | cin >> e.u >> e.v >> e.w; 36 | --e.u; --e.v; 37 | } 38 | 39 | bool changed; 40 | vector p(n, -1); 41 | vector d(n); 42 | for(i = 0; i < n; i++) { 43 | changed = false; 44 | for(auto& e: edges) 45 | if(chmin(d[e.v], d[e.u] + e.w)) 46 | changed = true, x = e.v, p[e.v] = e.u; 47 | } 48 | 49 | if(!changed) return cout << "NO" << '\n', 0; 50 | 51 | for(i = 0; i < n; i++) x = p[x]; 52 | vector ans; ans.reserve(n); 53 | i = x; 54 | do { ans.pb(i); i = p[i]; } while(i ^ x); 55 | ans.pb(i); 56 | reverse(all(ans)); 57 | 58 | cout << "YES" << '\n'; 59 | for(auto& x: ans) 60 | cout << x+1 << ' '; 61 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Flight Discount.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 18.05.2021 01:42:23 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t k_II = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 2e5 + 5; 20 | 21 | int main() { 22 | cin.tie(nullptr)->sync_with_stdio(false); 23 | int i, n, m; 24 | cin >> n >> m; 25 | vector>> g(n); 26 | for(i = 0; i < m; i++) { 27 | int u, v, w; cin >> u >> v >> w; 28 | g[--u].pb(--v, w); 29 | } 30 | 31 | struct state { 32 | int v, o; int64_t dist; 33 | state(int v, int o, int64_t dist): v(v), o(o), dist(dist) {} 34 | bool operator<(const state& o) const { 35 | return dist > o.dist; 36 | } 37 | }; 38 | 39 | array, 2> d; 40 | d[0] = d[1] = vector(n, k_II); 41 | priority_queue pq; 42 | pq.emplace(0, 0, d[0][0] = 0); 43 | while(!pq.empty()) { 44 | state top = pq.top(); pq.pop(); 45 | if(top.dist > d[top.o][top.v]) continue; 46 | for(auto& [to, w]: g[top.v]) { 47 | if(chmin(d[top.o][to], top.dist + w)) 48 | pq.emplace(to, top.o, d[top.o][to]); 49 | if(!top.o and chmin(d[1][to], top.dist + w/2)) 50 | pq.emplace(to, 1, d[1][to]); 51 | } 52 | } 53 | 54 | cout << min(d[0].back(), d[1].back()); 55 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Flight Routes.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.09.2021 00:24:44 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t k_II = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 2e5 + 5; 20 | 21 | int main() { 22 | ios_base::sync_with_stdio(false), cin.tie(nullptr); 23 | int i, n, m, k; 24 | cin >> n >> m >> k; 25 | vector>> g(n); 26 | for(i = 0; i < m; i++) { 27 | int u, v, w; cin >> u >> v >> w; 28 | g[--u].pb(--v, w); 29 | } 30 | 31 | struct state { 32 | int v; int64_t dist; 33 | state(int v, int64_t dist): v(v), dist(dist) {} 34 | bool operator<(const state& o) const { 35 | return dist > o.dist; 36 | } 37 | }; 38 | 39 | vector d(n, vector(k, k_II)); 40 | priority_queue pq; 41 | pq.emplace(0, d[0][0] = 0); 42 | while(!pq.empty()) { 43 | state top = pq.top(); pq.pop(); 44 | if(top.dist > d[top.v][k - 1]) continue; 45 | for(auto& [to, w]: g[top.v]) 46 | if(chmin(d[to][k - 1], top.dist + w)) 47 | pq.emplace(to, top.dist + w), sort(all(d[to])); 48 | } 49 | 50 | for(auto& x: d[n - 1]) 51 | cout << x << ' '; 52 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Game Routes.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 19.05.2021 18:22:59 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t k_II = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 2e5 + 5; 20 | 21 | int main() { 22 | cin.tie(nullptr)->sync_with_stdio(false); 23 | int i, n, m; 24 | cin >> n >> m; 25 | vector> g(n); 26 | vector indeg(n); 27 | for(i = 0; i < m; i++) { 28 | int u, v; cin >> u >> v; u--, v--; 29 | g[u].pb(v); indeg[v]++; 30 | } 31 | 32 | queue q; 33 | vector order; order.reserve(n); 34 | for(i = 0; i < n; i++) 35 | if(!indeg[i]) q.push(i); 36 | while(!q.empty()) { 37 | auto v = q.front(); q.pop(); 38 | order.pb(v); 39 | for(auto& x: g[v]) 40 | if(!--indeg[x]) q.push(x); 41 | } 42 | 43 | vector dp(n); dp[0] = 1; 44 | for(auto& v: order) { 45 | for(auto& x: g[v]) { 46 | dp[x] += dp[v]; 47 | if(dp[x] >= MOD) 48 | dp[x] -= MOD; 49 | } 50 | } 51 | 52 | cout << dp[n-1]; 53 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Hamiltonian Flights.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.09.2021 20:31:44 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t k_II = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | ios_base::sync_with_stdio(false), cin.tie(nullptr); 21 | int i, j, n, m; 22 | cin >> n >> m; 23 | vector adj(n, vector(n)); 24 | while(m--) { 25 | int u, v; cin >> u >> v; 26 | adj[--u][--v]++; 27 | } 28 | 29 | vector dp(1 << n, vector(n)); 30 | dp[1][0] = 1; 31 | 32 | for(int mask = 1; mask < 1 << n; mask++) { 33 | for(i = 0; i < n; i++) if(mask >> i & 1 and dp[mask][i]) { 34 | for(j = 1; j < n; j++) if(~mask >> j & 1 and adj[i][j]) { 35 | dp[mask | 1 << j][j] += dp[mask][i] * adj[i][j]; 36 | dp[mask | 1 << j][j] %= MOD; 37 | } 38 | } 39 | } 40 | 41 | cout << dp[(1 << n) - 1][n - 1]; 42 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Investigation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 28.08.2021 00:10:58 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t k_II = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 2e5 + 5; 20 | 21 | int main() { 22 | ios_base::sync_with_stdio(false), cin.tie(nullptr); 23 | int i, n, m; 24 | cin >> n >> m; 25 | vector>> g(n); 26 | for(i = 0; i < m; i++) { 27 | int u, v, w; cin >> u >> v >> w; 28 | g[--u].pb(--v, w); 29 | } 30 | 31 | struct state { 32 | int v; int64_t dist; 33 | state(int v, int64_t dist): v(v), dist(dist) {} 34 | bool operator<(const state& o) const { 35 | return dist > o.dist; 36 | } 37 | }; 38 | 39 | vector ways(n), mn(n), mx(n); 40 | ways[0] = 1; 41 | 42 | vector d(n, k_II); 43 | priority_queue pq; 44 | pq.emplace(0, d[0] = 0); 45 | 46 | while(!pq.empty()) { 47 | state top = pq.top(); pq.pop(); 48 | if(top.dist > d[top.v]) continue; 49 | for(auto& [to, w]: g[top.v]) { 50 | if(d[to] == top.dist + w) { 51 | ways[to] += ways[top.v]; 52 | if(ways[to] >= MOD) ways[to] -= MOD; 53 | mn[to] = min(mn[to], mn[top.v] + 1); 54 | mx[to] = max(mx[to], mx[top.v] + 1); 55 | } else if(chmin(d[to], top.dist + w)) { 56 | ways[to] = ways[top.v]; 57 | mn[to] = mn[top.v] + 1; mx[to] = mx[top.v] + 1; 58 | pq.emplace(to, d[to]); 59 | } 60 | } 61 | } 62 | 63 | cout << d.back() << ' ' << ways.back() << ' ' << mn.back() << ' ' << mx.back(); 64 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Labyrinth.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 17.05.2021 22:03:26 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const array dx{1, 0, -1, 0}; 16 | const array dy{0, 1, 0, -1}; 17 | const string dir = "ULDR"; 18 | 19 | const int64_t k_II = 2e18; 20 | const int INF = 2e9, MOD = 1e9+7; 21 | const int N = 2e5 + 5; 22 | 23 | int main() { 24 | cin.tie(nullptr)->sync_with_stdio(false); 25 | int i, j, n, m, stx, sty, ex, ey; 26 | cin >> n >> m; 27 | vector a(n); 28 | for(auto& x: a) cin >> x; 29 | 30 | for(i = 0; i < n; i++) 31 | for(j = 0; j < m; j++) 32 | if(a[i][j] == 'A') 33 | stx = i, sty = j; 34 | else if(a[i][j] == 'B') 35 | ex = i, ey = j; 36 | 37 | 38 | auto valid = [&](int x, int y) { 39 | return 0 <= x and x < n and 0 <= y and y < m and a[x][y] != '#'; 40 | }; 41 | 42 | vector> d(n, vector(m, -1)); 43 | vector> p(n, vector(m, -1)); 44 | queue> q; 45 | d[stx][sty] = 0; q.emplace(stx, sty); 46 | 47 | while(!q.empty()) { 48 | auto [x, y] = q.front(); q.pop(); 49 | for(int z = 0; z < 4; z++) { 50 | int nx = x + dx[z]; 51 | int ny = y + dy[z]; 52 | if(valid(nx, ny) and d[nx][ny] == -1) { 53 | d[nx][ny] = d[x][y] + 1; 54 | p[nx][ny] = z + 2 & 3; 55 | q.emplace(nx, ny); 56 | } 57 | } 58 | } 59 | 60 | if(d[ex][ey] == -1) 61 | return cout << "NO" << '\n', 0; 62 | 63 | string ans; 64 | while(ex != stx or ey != sty) { 65 | ans += dir[p[ex][ey]]; 66 | tie(ex, ey) = pair{ex + dx[p[ex][ey]], ey + dy[p[ex][ey]]}; 67 | } reverse(all(ans)); 68 | 69 | cout << "YES" << '\n'; 70 | cout << sz(ans) << '\n'; 71 | cout << ans << '\n'; 72 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Longest Flight Route.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.09.2021 00:33:57 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t k_II = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 2e5 + 5; 20 | 21 | int main() { 22 | ios_base::sync_with_stdio(false), cin.tie(nullptr); 23 | int i, n, m; 24 | cin >> n >> m; 25 | vector indeg(n); 26 | vector> g(n); 27 | for(i = 0; i < m; i++) { 28 | int u, v; cin >> u >> v; 29 | g[--u].pb(--v); indeg[v]++; 30 | } 31 | 32 | vector par(n, -1), dp(n, -INF); 33 | dp[0] = 1; 34 | 35 | queue q; 36 | for(i = 0; i < n; i++) 37 | if(!indeg[i]) q.push(i); 38 | 39 | while(!q.empty()) { 40 | auto v = q.front(); q.pop(); 41 | for(auto& x: g[v]) { 42 | if(!--indeg[x]) q.push(x); 43 | if(chmax(dp[x], dp[v] + 1)) par[x] = v; 44 | } 45 | } 46 | 47 | if(dp[n - 1] < 0) 48 | return cout << "IMPOSSIBLE" << '\n', 0; 49 | 50 | vector ans; 51 | ans.reserve(dp[n - 1]); 52 | for(i = n-1; ~i; i = par[i]) ans.pb(i); 53 | reverse(all(ans)); 54 | 55 | cout << sz(ans) << '\n'; 56 | for(auto& x: ans) cout << x + 1 << ' '; 57 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Mail Delivery.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.03.2021 19:01:10 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | struct edge_t { 25 | int u{-1}, v{-1}; int64_t w{0}; bool done{false}; 26 | edge_t() = default; 27 | edge_t(int u, int v, int64_t w = 0) : u(u), v(v), w(w) {} 28 | bool operator<(const edge_t& other) { return w < other.w; } 29 | friend ostream& operator<<(ostream& os, const edge_t& e) { os << e.u << ' ' << e.v << ' ' << e.w; return os; } 30 | }; 31 | 32 | const int64_t DESPACITO = 2e18; 33 | const int INF = 2e9, MOD = 1e9+7; 34 | const int N = 2e5 + 5; 35 | 36 | int main() { 37 | cin.tie(nullptr)->sync_with_stdio(false); 38 | int i, n, m; 39 | cin >> n >> m; 40 | 41 | vector deg(n); 42 | vector edges; 43 | edges.reserve(m); 44 | vector> g(n); 45 | 46 | for(i = 0; i < m; i++) { 47 | int u, v; cin >> u >> v; 48 | deg[--u]++; deg[--v]++; 49 | edges.pb(u, v); 50 | g[u].pb(&edges.back()); 51 | g[v].pb(&edges.back()); 52 | } 53 | 54 | bool bad = false; 55 | for(i = 0; i < n; i++) 56 | bad |= deg[i] & 1; 57 | 58 | if(bad) 59 | return cout << "IMPOSSIBLE" << '\n', 0; 60 | 61 | vector tour; 62 | tour.reserve(m+1); 63 | Y([&](auto dfs, int v) -> void { 64 | while(deg[v]-- > 0) { 65 | auto e = g[v][deg[v]]; 66 | if(!e->done) 67 | e->done = true, dfs(e->u ^ e->v ^ v); 68 | } tour.pb(v); 69 | })(0); 70 | 71 | for(i = 0; i < n; i++) 72 | if(deg[i] > 0) 73 | return cout << "IMPOSSIBLE" << '\n', 0; 74 | 75 | reverse(all(tour)); 76 | for(auto& x: tour) cout << ++x << ' '; 77 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Message Route.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 17.05.2021 22:39:20 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t k_II = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, m; 22 | cin >> n >> m; 23 | vector> g(n); 24 | for(i = 0; i < m; i++) { 25 | int u, v; cin >> u >> v; u--, v--; 26 | g[u].pb(v); g[v].pb(u); 27 | } 28 | 29 | queue q; q.push(0); 30 | vector d(n, -1), p(n, -1); d[0] = 0; 31 | while(!q.empty()) { 32 | auto cur = q.front(); q.pop(); 33 | for(auto nxt : g[cur]) { 34 | if(d[nxt] == -1) { 35 | d[nxt] = d[cur] + 1; 36 | p[nxt] = cur; 37 | q.push(nxt); 38 | } 39 | } 40 | } 41 | 42 | if(d.back() == -1) 43 | return cout << "IMPOSSIBLE" << '\n', 0; 44 | 45 | i = n-1; 46 | vector ans; ans.reserve(d.back()); 47 | while(~i) ans.pb(exchange(i, p[i])); 48 | reverse(all(ans)); 49 | 50 | cout << d.back()+1 << '\n'; 51 | for(auto x: ans) cout << x+1 << ' '; 52 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Road Construction.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.09.2021 01:01:32 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t k_II = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | ios_base::sync_with_stdio(false), cin.tie(nullptr); 21 | int n, m, mx = 1; 22 | cin >> n >> m; 23 | 24 | vector par(n + 1, -1); 25 | auto get_par = [&par](int A) { 26 | while(par[A] >= 0) { 27 | if(par[par[A]] >= 0) 28 | par[A] = par[par[A]]; 29 | A = par[A]; 30 | } return A; 31 | }; 32 | 33 | auto merge = [&get_par, &par](int A, int B) { 34 | A = get_par(A); B = get_par(B); 35 | if(A == B) return false; 36 | if(-par[A] < -par[B]) swap(A, B); 37 | par[A] += par[B]; par[B] = A; 38 | return true; 39 | }; 40 | 41 | while(m--) { 42 | int u, v; cin >> u >> v; 43 | if(merge(u, v)) n--; 44 | mx = max(mx, -par[get_par(u)]); 45 | cout << n << ' ' << mx << '\n'; 46 | } 47 | 48 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Road Reparation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.09.2021 00:55:27 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | struct edge_t { 16 | int u{-1}, v{-1}; int64_t w{0}; 17 | edge_t() = default; 18 | edge_t(int u, int v, int64_t w = 0) : u(u), v(v), w(w) {} 19 | bool operator<(const edge_t& other) { return w < other.w; } 20 | }; 21 | 22 | const int64_t k_II = 2e18; 23 | const int INF = 2e9, MOD = 1e9+7; 24 | const int N = 2e5 + 5; 25 | 26 | int main() { 27 | ios_base::sync_with_stdio(false), cin.tie(nullptr); 28 | int n, m, cnt = 0; 29 | cin >> n >> m; 30 | 31 | vector edges(m); 32 | for(auto& e: edges) 33 | cin >> e.u >> e.v >> e.w; 34 | sort(all(edges)); 35 | 36 | vector par(n + 1, -1); 37 | auto get_par = [&par](int A) { 38 | while(par[A] >= 0) { 39 | if(par[par[A]] >= 0) 40 | par[A] = par[par[A]]; 41 | A = par[A]; 42 | } return A; 43 | }; 44 | 45 | auto merge = [&get_par, &par](int A, int B) { 46 | A = get_par(A); B = get_par(B); 47 | if(A == B) return false; 48 | if(-par[A] < -par[B]) swap(A, B); 49 | par[A] += par[B]; par[B] = A; 50 | return true; 51 | }; 52 | 53 | int64_t ans = 0; 54 | for(auto& e: edges) 55 | if(merge(e.u, e.v)) 56 | ans += e.w, cnt++; 57 | 58 | if(cnt < n - 1) 59 | cout << "IMPOSSIBLE" << '\n'; 60 | else 61 | cout << ans << '\n'; 62 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Round Trip II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 18.05.2021 12:06:35 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | const int64_t k_II = 2e18; 25 | const int INF = 2e9, MOD = 1e9+7; 26 | const int N = 2e5 + 5; 27 | 28 | int main() { 29 | cin.tie(nullptr)->sync_with_stdio(false); 30 | int i, n, m; 31 | cin >> n >> m; 32 | vector> g(n); 33 | for(i = 0; i < m; i++) { 34 | int u, v; cin >> u >> v; 35 | g[--u].pb(--v); 36 | } 37 | 38 | int head = -1; 39 | vector vis(n), ans; 40 | ans.reserve(n); 41 | for(i = 0; i < n; i++) 42 | if(!vis[i]) 43 | Y([&](auto dfs, int v) -> void { 44 | vis[v] = 1; 45 | for(auto& x: g[v]) if(head == -1) { 46 | if(!vis[x]) dfs(x); 47 | else if(vis[x] == 1) 48 | ans.pb(head = x); 49 | } vis[v] = 2; 50 | if(~head and head < n) ans.pb(v); 51 | if(v == head) head = n; 52 | })(i); 53 | 54 | reverse(all(ans)); 55 | if(ans.empty()) 56 | return cout << "IMPOSSIBLE" << '\n', 0; 57 | 58 | cout << sz(ans) << '\n'; 59 | for(auto& x: ans) 60 | cout << x+1 << ' '; 61 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Round Trip.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 17.05.2021 23:01:22 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | 25 | const int64_t k_II = 2e18; 26 | const int INF = 2e9, MOD = 1e9+7; 27 | const int N = 2e5 + 5; 28 | 29 | int main() { 30 | cin.tie(nullptr)->sync_with_stdio(false); 31 | int i, n, m; 32 | cin >> n >> m; 33 | vector> g(n); 34 | for(i = 0; i < m; i++) { 35 | int u, v; cin >> u >> v; u--, v--; 36 | g[u].pb(v); g[v].pb(u); 37 | } 38 | 39 | int head = -1; 40 | vector vis(n), ans; 41 | ans.reserve(n); 42 | 43 | auto dfs = Y([&](auto dfs, int v, int p) -> void { 44 | vis[v] = true; 45 | for(auto& x: g[v]) if(x^p and head == -1) { 46 | if(vis[x] and ans.empty()) head = x; 47 | if(!vis[x]) dfs(x, v); 48 | } 49 | if(~head) { 50 | ans.pb(v); 51 | if(v == head) 52 | head = -1; 53 | } 54 | }); 55 | 56 | for(i = 0; i < n; i++) 57 | if(!vis[i]) dfs(i, -1); 58 | 59 | if(ans.empty()) 60 | return cout << "IMPOSSIBLE" << '\n', 0; 61 | 62 | cout << sz(ans)+1 << '\n'; 63 | for(auto& x: ans) 64 | cout << x+1 << ' '; 65 | cout << ans.front()+1; 66 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Shortest Routes I.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 18.05.2021 00:21:28 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t k_II = 2e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 2e5 + 5; 20 | 21 | int main() { 22 | cin.tie(nullptr)->sync_with_stdio(false); 23 | int i, n, m; 24 | cin >> n >> m; 25 | vector>> g(n); 26 | for(i = 0; i < m; i++) { 27 | int u, v, w; cin >> u >> v >> w; 28 | g[--u].pb(--v, w); 29 | } 30 | 31 | struct state { 32 | int v; int64_t dist; 33 | state(int v, int64_t dist): v(v), dist(dist) {} 34 | bool operator<(const state& o) const { 35 | return dist > o.dist; 36 | } 37 | }; 38 | 39 | vector d(n, k_II); 40 | priority_queue pq; 41 | pq.emplace(0, d[0] = 0); 42 | while(!pq.empty()) { 43 | state top = pq.top(); pq.pop(); 44 | if(top.dist > d[top.v]) continue; 45 | for(auto& [to, w]: g[top.v]) 46 | if(chmin(d[to], top.dist + w)) 47 | pq.emplace(to, d[to]); 48 | } 49 | 50 | for(i = 0; i < n; i++) 51 | cout << d[i] << " \n"[i == n-1]; 52 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Shortest Routes II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 18.05.2021 00:28:26 4 | **/ 5 | #ifdef W 6 | #include 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | const int64_t k_II = 1e18; 18 | const int INF = 2e9, MOD = 1e9+7; 19 | const int N = 500 + 5; 20 | int64_t d[N][N]; 21 | 22 | int main() { 23 | cin.tie(nullptr)->sync_with_stdio(false); 24 | int i, j, k, n, m, Q; 25 | cin >> n >> m >> Q; 26 | for(i = 0; i < n; i++) 27 | for(j = 0; j < n; j++) 28 | if(i ^ j) d[i][j] = k_II; 29 | 30 | for(i = 0; i < m; i++) { 31 | int u, v, w; cin >> u >> v >> w; --u; --v; 32 | chmin(d[u][v], w); chmin(d[v][u], w); 33 | } 34 | 35 | for(k = 0; k < n; k++) 36 | for(i = 0; i < n; i++) 37 | for(j = 0; j < n; j++) 38 | chmin(d[i][j], d[i][k] + d[k][j]); 39 | 40 | while(Q--) { 41 | int u, v; cin >> u >> v; --u; --v; 42 | cout << (d[u][v] == k_II? -1 : d[u][v]) << '\n'; 43 | } 44 | } // ~W -------------------------------------------------------------------------------- /CSES/Graph Algorithms/Teleporters Path.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 06.03.2021 19:01:10 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | struct edge_t { 25 | int u{-1}, v{-1}; int64_t w{0}; 26 | edge_t() = default; 27 | edge_t(int u, int v, int64_t w = 0) : u(u), v(v), w(w) {} 28 | bool operator<(const edge_t& other) { return w < other.w; } 29 | friend ostream& operator<<(ostream& os, const edge_t& e) { os << e.u << ' ' << e.v << ' ' << e.w; return os; } 30 | }; 31 | 32 | const int64_t DESPACITO = 2e18; 33 | const int INF = 2e9, MOD = 1e9+7; 34 | const int N = 2e5 + 5; 35 | 36 | int main() { 37 | cin.tie(nullptr)->sync_with_stdio(false); 38 | int i, n, m; 39 | cin >> n >> m; 40 | vector indeg(n), outdeg(n); 41 | vector> g(n); 42 | for(i = 0; i < m; i++) { 43 | int u, v; cin >> u >> v; 44 | outdeg[--u]++; indeg[--v]++; 45 | g[u].pb(v); 46 | } 47 | 48 | bool bad = false; 49 | for(i = 1; i < n-1; i++) 50 | bad |= outdeg[i] ^ indeg[i]; 51 | 52 | bad |= outdeg[0]-indeg[0] ^ 1; 53 | bad |= indeg[n-1]-outdeg[n-1] ^ 1; 54 | 55 | if(bad) 56 | return cout << "IMPOSSIBLE" << '\n', 0; 57 | 58 | vector tour; 59 | tour.reserve(m+1); 60 | Y([&](auto dfs, int v) -> void { 61 | while(outdeg[v]-- > 0) 62 | dfs(g[v][outdeg[v]]); 63 | tour.pb(v); 64 | })(0); 65 | 66 | for(i = 0; i < n; i++) 67 | if(outdeg[i] > 0) 68 | return cout << "IMPOSSIBLE" << '\n', 0; 69 | 70 | reverse(all(tour)); 71 | for(auto& x: tour) cout << ++x << ' '; 72 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Apartments.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 03.02.2021 00:51:35 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, j, n, m, k, ans = 0; 22 | cin >> n >> m >> k; 23 | vector a(n), b(m); 24 | for(auto& x: a) cin >> x; 25 | for(auto& x: b) cin >> x; 26 | sort(all(a)); sort(all(b)); 27 | 28 | for(i = j = 0; i < n; i++) { 29 | while(j < m and b[j] < a[i]-k) j++; 30 | if(j < m and b[j] <= a[i]+k) ans++, j++; 31 | } 32 | 33 | cout << ans; 34 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Array Division.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 16:17:31 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, k; 22 | cin >> n >> k; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | 26 | auto check = [&a, k](int64_t x) { 27 | int p = 1; int64_t cur = 0; 28 | for(auto y: a) { 29 | if(cur + y > x) 30 | p++, cur = 0; 31 | cur += y; 32 | } return p <= k; 33 | }; 34 | 35 | int64_t lo = *max_element(all(a)), hi = DESPACITO; 36 | while(lo <= hi) { 37 | int64_t mid = lo + hi >> 1; 38 | if(check(mid)) hi = mid - 1; 39 | else lo = mid + 1; 40 | } cout << lo; 41 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Collecting Numbers II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 11:59:45 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, m, ans = 0; 22 | cin >> n >> m; 23 | vector pos(n+2, INF), a(n+2); 24 | for(i = 1; i <= n; i++) { 25 | cin >> a[i]; 26 | pos[a[i]] = i; 27 | } 28 | 29 | for(i = 1; i <= n; i++) 30 | ans += pos[i] < pos[i-1]; 31 | 32 | auto upd = [&](int x, int delta) { 33 | ans += pos[x] < pos[x-1]? delta : 0; 34 | ans += pos[x+1] < pos[x]? delta : 0; 35 | }; 36 | 37 | while(m--) { 38 | int x, y; cin >> x >> y; 39 | upd(a[x], -1); upd(a[y], -1); 40 | swap(a[x], a[y]); pos[a[x]] = x; pos[a[y]] = y; 41 | upd(a[x], +1); upd(a[y], +1); 42 | if(abs(a[x]-a[y]) == 1) { 43 | int p = min(a[x], a[y]), q = max(a[x], a[y]); 44 | ans += pos[p] < pos[q]? +1 : -1; 45 | } 46 | cout << ans << '\n'; 47 | } 48 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Collecting Numbers.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 11:59:45 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, ans = 1; 22 | cin >> n; 23 | vector pos(n); 24 | for(i = 0; i < n; i++) { 25 | int x; cin >> x; 26 | pos[--x] = i; 27 | } 28 | 29 | for(i = 1; i < n; i++) 30 | ans += pos[i] < pos[i-1]; 31 | 32 | cout << ans; 33 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Concert Tickets.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 03.02.2021 01:26:32 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, m; 22 | cin >> n >> m; 23 | multiset s; 24 | for(i = 0; i < n; i++) { 25 | int x; cin >> x; 26 | s.insert(-x); 27 | } 28 | 29 | while(m--) { 30 | int x; cin >> x; 31 | auto it = s.lower_bound(-x); 32 | if(it == s.end()) 33 | cout << -1 << '\n'; 34 | else { 35 | cout << -*it << '\n'; 36 | s.erase(it); 37 | } 38 | } 39 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Distinct Numbers.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 03.02.2021 01:31:05 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; 22 | cin >> n; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | sort(all(a)); 26 | a.erase(unique(all(a)), a.end()); 27 | cout << sz(a); 28 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Factory Machines.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 11:55:36 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 1.05e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; int64_t k; 22 | cin >> n >> k; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | 26 | auto check = [&a, k](int64_t t) { 27 | int64_t res = 0; 28 | for(auto& x: a) { 29 | res += t / x; 30 | if(res >= k) return true; 31 | } 32 | return res >= k; 33 | }; 34 | 35 | int64_t lo = 1, hi = DESPACITO; 36 | while(lo <= hi) { 37 | int64_t mid = lo + hi >> 1; 38 | if(check(mid)) hi = mid - 1; 39 | else lo = mid + 1; 40 | } cout << lo; 41 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Ferris Wheel.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 03.02.2021 00:56:58 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, j, n, x, ans = 0; 22 | cin >> n >> x; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | sort(all(a)); 26 | for(i = 0, j = n-1; i < j; j--) { 27 | if(a[i] + a[j] <= x) i++; 28 | ans++; 29 | } if(i == j) ans++; 30 | 31 | cout << ans; 32 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Josephus Problem I.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 13:21:34 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | #include 15 | #include 16 | using namespace __gnu_pbds; 17 | template> 18 | using ordered_set = tree; 19 | #define ook order_of_key // count of elements strictly smaller than k 20 | #define fbo find_by_order // iterator to kth element starting from 0 21 | 22 | const int64_t DESPACITO = 2e18; 23 | const int INF = 2e9, MOD = 1e9+7; 24 | const int N = 2e5 + 5; 25 | 26 | int main() { 27 | cin.tie(nullptr)->sync_with_stdio(false); 28 | int i, n, k = 1, pos = 0; 29 | cin >> n; 30 | ordered_set os; 31 | for(i = 1; i <= n; i++) 32 | os.insert(i); 33 | do { 34 | pos = (pos + k) % n; 35 | auto it = os.fbo(pos); 36 | cout << *it << " \n"[i == n]; 37 | os.erase(it); 38 | } while(--n); 39 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Josephus Problem II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 13:21:34 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | #include 15 | #include 16 | using namespace __gnu_pbds; 17 | template> 18 | using ordered_set = tree; 19 | #define ook order_of_key // count of elements strictly smaller than k 20 | #define fbo find_by_order // iterator to kth element starting from 0 21 | 22 | const int64_t DESPACITO = 2e18; 23 | const int INF = 2e9, MOD = 1e9+7; 24 | const int N = 2e5 + 5; 25 | 26 | int main() { 27 | cin.tie(nullptr)->sync_with_stdio(false); 28 | int i, n, k, pos = 0; 29 | cin >> n >> k; 30 | ordered_set os; 31 | for(i = 1; i <= n; i++) 32 | os.insert(i); 33 | do { 34 | pos = (pos + k) % n; 35 | auto it = os.fbo(pos); 36 | cout << *it << " \n"[i == n]; 37 | os.erase(it); 38 | } while(--n); 39 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Maximum Subarray Sum II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 15:31:06 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | int a[N]; 19 | int64_t pref[N]; 20 | 21 | int main() { 22 | cin.tie(nullptr)->sync_with_stdio(false); 23 | int i, n, x, y; int64_t ans = -DESPACITO; 24 | cin >> n >> x >> y; 25 | for(i = 1; i <= n; i++) { 26 | cin >> a[i]; 27 | pref[i] = pref[i-1] + a[i]; 28 | } 29 | 30 | multiset ms; 31 | for(i = 1; i <= n; i++) { 32 | if(i-x >= 0) ms.insert(pref[i-x]); 33 | if(!ms.empty()) ans = max(ans, pref[i] - *ms.begin()); 34 | if(i-y >= 0) ms.erase(ms.find(pref[i-y])); 35 | } 36 | 37 | cout << ans; 38 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Maximum Subarray Sum.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 11:41:10 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; int64_t cur = 0, ans = -DESPACITO; 22 | cin >> n; 23 | for(i = 0; i < n; i++) { 24 | int x; cin >> x; 25 | cur += x; 26 | ans = max(ans, cur); 27 | if(cur < 0) cur = 0; 28 | } cout << ans; 29 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Missing Coin Sum.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 11:56:37 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; int64_t ans = 1; 22 | cin >> n; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | sort(all(a)); 26 | for(auto& x: a) { 27 | if(x > ans) break; 28 | ans += x; 29 | } cout << ans; 30 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Movie Festival II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 16:31:28 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, k, ans = 0; 22 | cin >> n >> k; 23 | vector> a(n); 24 | for(auto& [r, l]: a) cin >> l >> r; 25 | sort(all(a)); 26 | 27 | multiset have; 28 | for(i = 0; i < k; i++) 29 | have.insert(0); 30 | 31 | for(auto& [r, l]: a) { 32 | auto it = have.upper_bound(l); 33 | if(it != have.begin()) { 34 | have.erase(--it); 35 | ans++; have.insert(r); 36 | } 37 | } cout << ans; 38 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Movie Festival.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 11:29:35 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int n, ans = 0, cur = -1; 22 | cin >> n; 23 | vector> events(n); 24 | for(auto &[x, y]: events) cin >> y >> x; 25 | sort(all(events)); 26 | for(auto &[x, y]: events) 27 | if(y >= cur) ans++, cur = x; 28 | cout << ans; 29 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Nearest Smaller Values.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 15:48:39 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; 22 | cin >> n; 23 | vector a(n); 24 | stack st; 25 | for(i = 0; i < n; i++) { 26 | cin >> a[i]; 27 | while(!st.empty() and a[st.top()] >= a[i]) 28 | st.pop(); 29 | cout << (st.empty()? 0 : st.top() + 1) << " \n"[i == n-1]; 30 | st.push(i); 31 | } 32 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Nested Ranges Check.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 13:41:04 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | #include 15 | #include 16 | using namespace __gnu_pbds; 17 | template> 18 | using ordered_set = tree; 19 | #define ook order_of_key // count of elements strictly smaller than k 20 | #define fbo find_by_order // iterator to kth element starting from 0 21 | 22 | const int64_t DESPACITO = 2e18; 23 | const int INF = 2e9, MOD = 1e9+7; 24 | const int N = 2e5 + 5; 25 | 26 | int main() { 27 | cin.tie(nullptr)->sync_with_stdio(false); 28 | int i = 0, n; 29 | cin >> n; 30 | 31 | vector> a(n); 32 | ordered_set> start, end; 33 | vector inside(n), outside(n); 34 | 35 | for(auto& [l, r, idx]: a) { 36 | cin >> l >> r; idx = i++; 37 | end.insert({l, idx}); 38 | } 39 | 40 | sort(all(a), [](const auto& A, const auto& B) { 41 | return A[1] == B[1]? A[0] > B[0] : A[1] < B[1]; 42 | }); 43 | 44 | for(i = 0; i < n; i++) { 45 | inside[a[i][2]] = sz(start) - start.ook({a[i][0], -1}); 46 | start.insert({a[i][0], a[i][2]}); 47 | end.erase({a[i][0], a[i][2]}); 48 | outside[a[i][2]] = end.ook({a[i][0], INF}); 49 | } 50 | 51 | for(i = 0; i < n; i++) 52 | cout << !!inside[i] << " \n"[i == n-1]; 53 | for(i = 0; i < n; i++) 54 | cout << !!outside[i] << " \n"[i == n-1]; 55 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Nested Ranges Count.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 13:41:04 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | #include 15 | #include 16 | using namespace __gnu_pbds; 17 | template> 18 | using ordered_set = tree; 19 | #define ook order_of_key // count of elements strictly smaller than k 20 | #define fbo find_by_order // iterator to kth element starting from 0 21 | 22 | const int64_t DESPACITO = 2e18; 23 | const int INF = 2e9, MOD = 1e9+7; 24 | const int N = 2e5 + 5; 25 | 26 | int main() { 27 | cin.tie(nullptr)->sync_with_stdio(false); 28 | int i = 0, n; 29 | cin >> n; 30 | 31 | vector> a(n); 32 | ordered_set> start, end; 33 | vector inside(n), outside(n); 34 | 35 | for(auto& [l, r, idx]: a) { 36 | cin >> l >> r; idx = i++; 37 | end.insert({l, idx}); 38 | } 39 | 40 | sort(all(a), [](const auto& A, const auto& B) { 41 | return A[1] == B[1]? A[0] > B[0] : A[1] < B[1]; 42 | }); 43 | 44 | for(i = 0; i < n; i++) { 45 | inside[a[i][2]] = sz(start) - start.ook({a[i][0], -1}); 46 | start.insert({a[i][0], a[i][2]}); 47 | end.erase({a[i][0], a[i][2]}); 48 | outside[a[i][2]] = end.ook({a[i][0], INF}); 49 | } 50 | 51 | for(i = 0; i < n; i++) 52 | cout << inside[i] << " \n"[i == n-1]; 53 | for(i = 0; i < n; i++) 54 | cout << outside[i] << " \n"[i == n-1]; 55 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Playlist.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 12:24:38 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, j, n, ans = 0; 22 | cin >> n; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | set have; 26 | for(i = j = 0; i < n; i++) { 27 | while(j < n and !have.count(a[j])) 28 | have.insert(a[j++]); 29 | ans = max(ans, j-i); 30 | have.erase(a[i]); 31 | } cout << ans; 32 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Reading Books.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 13:37:30 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; 22 | cin >> n; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | cout << max(accumulate(all(a), 0LL), 2LL * *max_element(all(a))); 26 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Restaurant Customers.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 the_hyp0cr1t3 3 | 🍪 03.02.2021 01:32:07 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; 22 | cin >> n; 23 | vector> events; 24 | events.reserve(2*n); 25 | for(i = 0; i < n; i++) { 26 | int a, b; cin >> a >> b; 27 | events.pb(a, 1); events.pb(++b, 0); 28 | } sort(all(events)); 29 | 30 | int cur = 0, ans = 0; 31 | for(auto& [x, o]: events) { 32 | cur += o? 1 : -1; 33 | ans = max(ans, cur); 34 | } 35 | 36 | cout << ans; 37 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Room Allocation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 11:36:14 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i = 0, n, cnt = 0; 22 | cin >> n; 23 | vector> events(n); 24 | for(auto& [x, y, z]: events) 25 | cin >> x >> y, z = i++; 26 | sort(all(events)); 27 | 28 | vector ans(n); 29 | priority_queue, vector>, greater>> pq; 30 | for(auto& [l, r, idx]: events) { 31 | if(!pq.empty() and pq.top().first < l) { 32 | auto [x, y] = pq.top(); pq.pop(); 33 | pq.emplace(r, y); 34 | ans[idx] = y; 35 | } else { 36 | pq.emplace(r, ++cnt); 37 | ans[idx] = cnt; 38 | } 39 | } 40 | 41 | cout << cnt << '\n'; 42 | for(auto& x: ans) cout << x << ' '; 43 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Sliding Cost.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 15:42:39 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, k; 22 | cin >> n >> k; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | 26 | // pitcher pouring (Algorithms live) 27 | multiset> small; 28 | multiset big; 29 | int64_t small_sum = 0, big_sum = 0; 30 | 31 | auto normalize = [&]() { 32 | while(sz(small) > k+1>>1) { 33 | big.insert(*small.begin()); 34 | big_sum += *small.begin(); 35 | small_sum -= *small.begin(); 36 | small.erase(small.begin()); 37 | } 38 | while(sz(big) > k>>1) { 39 | small.insert(*big.begin()); 40 | small_sum += *big.begin(); 41 | big_sum -= *big.begin(); 42 | big.erase(big.begin()); 43 | } 44 | }; 45 | 46 | auto add = [&](int x) { 47 | if(small.empty() or x > *small.begin()) { 48 | big.insert(x); big_sum += x; 49 | } else { 50 | small.insert(x); small_sum += x; 51 | } 52 | }; 53 | 54 | auto remove = [&](int x) { 55 | if(x > *small.begin()) { 56 | big.erase(big.find(x)); big_sum -= x; 57 | } else { 58 | small.erase(small.find(x)); small_sum -= x; 59 | } 60 | }; 61 | 62 | for(i = 0; i < k-1; i++) 63 | add(a[i]); 64 | 65 | auto calc = [&](int64_t x) { 66 | return big_sum - x * (k/2) + x * (k+1>>1) - small_sum; 67 | }; 68 | 69 | for(i = k-1; i < n; i++) { 70 | add(a[i]); normalize(); 71 | cout << calc(*small.begin()) << " \n"[i == n-1]; 72 | remove(a[i-k+1]); 73 | } 74 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Sliding Median.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 15:42:39 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, k; 22 | cin >> n >> k; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | 26 | // pitcher pouring (Algorithms live) 27 | multiset> small; 28 | multiset big; 29 | 30 | auto normalize = [&]() { 31 | while(sz(small) > k+1>>1) { 32 | big.insert(*small.begin()); 33 | small.erase(small.begin()); 34 | } 35 | while(sz(big) > k>>1) { 36 | small.insert(*big.begin()); 37 | big.erase(big.begin()); 38 | } 39 | }; 40 | 41 | for(i = 0; i < k-1; i++) 42 | big.insert(a[i]); 43 | 44 | for(i = k-1; i < n; i++) { 45 | if(small.empty() or a[i] > *small.begin()) 46 | big.insert(a[i]); 47 | else small.insert(a[i]); 48 | normalize(); 49 | cout << *small.begin() << " \n"[i == n-1]; 50 | if(a[i-k+1] > *small.begin()) 51 | big.erase(big.find(a[i-k+1])); 52 | else small.erase(small.find(a[i-k+1])); 53 | } 54 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Stick Lengths.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 11:43:54 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 1e9; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; 22 | cin >> n; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | 26 | auto check = [&a](int k) { 27 | int64_t res = 0; 28 | for(auto& x: a) 29 | res += abs(x-k); 30 | return res; 31 | }; 32 | 33 | int lo = 1, hi = N; 34 | while(hi - lo > 3) { 35 | int mid = lo + hi >> 1; 36 | if(check(mid) >= check(mid+1)) 37 | lo = mid; 38 | else hi = mid + 1; 39 | } 40 | 41 | cout << min({check(lo), check(lo+1), check(lo+2), check(lo+3)}); 42 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Subarray Distinct Values.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 16:06:56 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | #include 15 | namespace Hashing { 16 | using hash_t = pair; 17 | static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 18 | 19 | struct custom_hash { 20 | static uint64_t splitmix64(uint64_t x) { 21 | x += 0x9e3779b97f4a7c15; 22 | x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; 23 | x = (x ^ (x >> 27)) * 0x94d049bb133111eb; 24 | return x ^ (x >> 31); 25 | } 26 | size_t operator()(uint64_t x) const { return splitmix64(x + FIXED_RANDOM); } 27 | size_t operator()(const hash_t& x) const { return splitmix64(FIXED_RANDOM + x.second) ^ (splitmix64(FIXED_RANDOM + x.first) << 1); } 28 | }; 29 | 30 | template 31 | using hash_map = __gnu_pbds::gp_hash_table; 32 | 33 | template 34 | using hash_set = hash_map; 35 | 36 | } using namespace Hashing; 37 | 38 | const int64_t DESPACITO = 2e18; 39 | const int INF = 2e9, MOD = 1e9+7; 40 | const int N = 2e5 + 5; 41 | 42 | int main() { 43 | cin.tie(nullptr)->sync_with_stdio(false); 44 | int i, j, n, k; int64_t ans = 0; 45 | cin >> n >> k; 46 | vector a(n); 47 | for(auto& x: a) cin >> x; 48 | 49 | hash_map have; 50 | for(i = j = 0; i < n; i++) { 51 | while(j < n and sz(have) < k) 52 | have[a[j++]]++; 53 | while(j < n and have.find(a[j]) != have.end()) 54 | have[a[j++]]++; 55 | ans += j-i; 56 | if(!--have[a[i]]) 57 | have.erase(a[i]); 58 | } cout << ans; 59 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Subarray Divisibility.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 15:52:45 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | #include 15 | namespace Hashing { 16 | using hash_t = pair; 17 | static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 18 | 19 | struct custom_hash { 20 | static uint64_t splitmix64(uint64_t x) { 21 | x += 0x9e3779b97f4a7c15; 22 | x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; 23 | x = (x ^ (x >> 27)) * 0x94d049bb133111eb; 24 | return x ^ (x >> 31); 25 | } 26 | size_t operator()(uint64_t x) const { return splitmix64(x + FIXED_RANDOM); } 27 | size_t operator()(const hash_t& x) const { return splitmix64(FIXED_RANDOM + x.second) ^ (splitmix64(FIXED_RANDOM + x.first) << 1); } 28 | }; 29 | 30 | template 31 | using hash_map = __gnu_pbds::gp_hash_table; 32 | 33 | template 34 | using hash_set = hash_map; 35 | 36 | } using namespace Hashing; 37 | 38 | const int64_t DESPACITO = 2e18; 39 | const int INF = 2e9, MOD = 1e9+7; 40 | const int N = 2e5 + 5; 41 | 42 | int main() { 43 | cin.tie(nullptr)->sync_with_stdio(false); 44 | int i, n, cur = 0; int64_t ans = 0; 45 | cin >> n; 46 | hash_map pref; 47 | pref[0] = 1; 48 | 49 | for(i = 0; i < n; i++) { 50 | int y; cin >> y; y %= n; 51 | if(y < 0) y += n; 52 | cur += y; 53 | if(cur >= n) cur -= n; 54 | ans += pref[cur]; 55 | pref[cur]++; 56 | } cout << ans; 57 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Subarray Sums I.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 15:52:45 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | #include 15 | namespace Hashing { 16 | using hash_t = pair; 17 | static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 18 | 19 | struct custom_hash { 20 | static uint64_t splitmix64(uint64_t x) { 21 | x += 0x9e3779b97f4a7c15; 22 | x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; 23 | x = (x ^ (x >> 27)) * 0x94d049bb133111eb; 24 | return x ^ (x >> 31); 25 | } 26 | size_t operator()(uint64_t x) const { return splitmix64(x + FIXED_RANDOM); } 27 | size_t operator()(const hash_t& x) const { return splitmix64(FIXED_RANDOM + x.second) ^ (splitmix64(FIXED_RANDOM + x.first) << 1); } 28 | }; 29 | 30 | template 31 | using hash_map = __gnu_pbds::gp_hash_table; 32 | 33 | template 34 | using hash_set = hash_map; 35 | 36 | } using namespace Hashing; 37 | 38 | const int64_t DESPACITO = 2e18; 39 | const int INF = 2e9, MOD = 1e9+7; 40 | const int N = 2e5 + 5; 41 | 42 | int main() { 43 | cin.tie(nullptr)->sync_with_stdio(false); 44 | int i, n; int64_t x, ans = 0, cur = 0; 45 | cin >> n >> x; 46 | hash_map pref; 47 | pref[0] = 1; 48 | 49 | for(i = 0; i < n; i++) { 50 | int64_t y; cin >> y; 51 | cur += y; 52 | ans += pref[cur-x]; 53 | pref[cur]++; 54 | } cout << ans; 55 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Subarray Sums II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 15:52:45 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; int64_t x, ans = 0, cur = 0; 22 | cin >> n >> x; 23 | map pref; 24 | pref[0] = 1; 25 | 26 | for(i = 0; i < n; i++) { 27 | int64_t y; cin >> y; 28 | cur += y; 29 | ans += pref[cur-x]; 30 | pref[cur]++; 31 | } cout << ans; 32 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Sum of Four Values.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 16:25:43 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, j, n, k; 22 | cin >> n >> k; 23 | vector a(n); 24 | for(auto& x: a) cin >> x; 25 | 26 | set> s; 27 | for(i = 0; i < n; i++) 28 | for(j = 0; j < i; j++) 29 | s.emplace(a[i] + a[j], j+1, i+1); 30 | 31 | for(i = 0; i < n; i++) { 32 | for(j = i+1; j < n; j++) 33 | s.erase({a[i] + a[j], i+1, j+1}); 34 | for(j = 0; j < i; j++) { 35 | auto it = s.lower_bound({k-a[i]-a[j], -1, -1}); 36 | if(it != s.end() and get<0>(*it) == k-a[i]-a[j]) { 37 | cout << j+1 << ' ' << i+1 << ' '; 38 | cout << get<1>(*it) << ' ' << get<2>(*it); 39 | return 0; 40 | } 41 | } 42 | } cout << "IMPOSSIBLE"; 43 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Sum of Three Values.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 16:25:43 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i = 0, j, n, k; 22 | cin >> n >> k; 23 | vector> a(n); 24 | for(auto& [x, y]: a) 25 | cin >> x, y = ++i; 26 | sort(all(a)); 27 | for(i = 0; i < n; i++) { 28 | for(j = 0; j < i; j++) { 29 | auto it = lower_bound(a.begin()+i+1, a.end(), array{k-a[i][0]-a[j][0], -1}); 30 | if(it != a.end() and (*it)[0] == k-a[i][0]-a[j][0]) 31 | return cout << a[j][1] << ' ' << a[i][1] << ' ' << (*it)[1], 0; 32 | } 33 | } cout << "IMPOSSIBLE"; 34 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Sum of Two Values.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 11:32:16 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i = 0, j, n, X; 22 | cin >> n >> X; 23 | vector> a(n); 24 | for(auto& [x, y]: a) cin >> x, y = ++i; 25 | sort(all(a)); 26 | for(i = 0, j = n-1; i < j; i++) { 27 | while(i < j and a[i].first + a[j].first > X) j--; 28 | if(i < j and a[i].first + a[j].first == X) 29 | return cout << a[i].second << ' ' << a[j].second, 0; 30 | } cout << "IMPOSSIBLE"; 31 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Tasks and Deadlines.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 12:10:12 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n; int64_t t = 0, ans = 0; 22 | cin >> n; 23 | vector> a(n); 24 | for(auto& [x, y]: a) cin >> x >> y; 25 | sort(all(a)); 26 | for(auto& [x, y]: a) { 27 | t += x; ans += 1LL * y - t; 28 | } cout << ans; 29 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Towers.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 12:28:41 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, n, ans = 0; 22 | cin >> n; 23 | multiset have; 24 | for(i = 0; i < n; i++) { 25 | int64_t x; cin >> x; 26 | auto it = have.upper_bound(x); 27 | if(it == have.end()) ans++; 28 | else have.erase(it); 29 | have.insert(x); 30 | } cout << ans; 31 | } // ~W -------------------------------------------------------------------------------- /CSES/Sorting and Searching/Traffic Lights.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 10.02.2021 12:41:50 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | const int64_t DESPACITO = 2e18; 16 | const int INF = 2e9, MOD = 1e9+7; 17 | const int N = 2e5 + 5; 18 | 19 | int main() { 20 | cin.tie(nullptr)->sync_with_stdio(false); 21 | int i, x, n; 22 | cin >> x >> n; 23 | multiset> diffs{0, x}; 24 | set points{0, x}; 25 | 26 | for(i = 0; i < n; i++) { 27 | int y; cin >> y; 28 | auto it = points.lower_bound(y); 29 | if(*it != y) { 30 | auto it2 = prev(it); 31 | int a = y - *it2, b = *it - y; 32 | diffs.erase(diffs.find(a + b)); 33 | diffs.insert(a); diffs.insert(b); 34 | points.insert(y); 35 | } cout << *diffs.begin() << ' '; 36 | } 37 | } // ~W -------------------------------------------------------------------------------- /CSES/Tree Algorithms/Company Queries I.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 12.02.2021 10:45:31 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | const int64_t DESPACITO = 2e18; 25 | const int INF = 2e9, MOD = 1e9+7; 26 | const int N = 2e5 + 5; 27 | const int LG = 20; 28 | 29 | int main() { 30 | cin.tie(nullptr)->sync_with_stdio(false); 31 | int i, n, Q; 32 | cin >> n >> Q; 33 | vector> g(n); 34 | for(i = 1; i < n; i++) { 35 | int p; cin >> p; 36 | g[--p].pb(i); 37 | } 38 | 39 | array, LG> anc; 40 | for(auto& x: anc) x.assign(n, -1); 41 | 42 | Y([&](auto dfs, int v, int p) -> void { 43 | anc[0][v] = p; 44 | for(int k = 1; k < LG; k++) 45 | anc[k][v] = ~anc[k-1][v]? anc[k-1][anc[k-1][v]] : -1; 46 | for(auto& x: g[v]) 47 | dfs(x, v); 48 | })(0, -1); 49 | 50 | auto walk = [&anc](int v, int d) { 51 | for(int k = LG-1; ~v and ~k; k--) 52 | if(d>>k & 1) v = anc[k][v]; 53 | return ~v? v+1 : v; 54 | }; 55 | 56 | while(Q--) { 57 | int x, d; cin >> x >> d; 58 | cout << walk(--x, d) << '\n'; 59 | } -------------------------------------------------------------------------------- /CSES/Tree Algorithms/Company Queries II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 12.02.2021 10:45:31 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | const int64_t DESPACITO = 2e18; 25 | const int INF = 2e9, MOD = 1e9+7; 26 | const int N = 2e5 + 5; 27 | const int LG = 20; 28 | 29 | int main() { 30 | cin.tie(nullptr)->sync_with_stdio(false); 31 | int i, n, Q; 32 | cin >> n >> Q; 33 | vector> g(n); 34 | for(i = 1; i < n; i++) { 35 | int p; cin >> p; 36 | g[--p].pb(i); 37 | } 38 | 39 | array, LG> anc; 40 | for(auto& x: anc) x.assign(n, -1); 41 | 42 | vector depth(n); 43 | Y([&](auto dfs, int v, int p) -> void { 44 | anc[0][v] = p; 45 | for(int k = 1; k < LG; k++) 46 | anc[k][v] = ~anc[k-1][v]? anc[k-1][anc[k-1][v]] : -1; 47 | for(auto& x: g[v]) 48 | depth[x] = depth[v] + 1, dfs(x, v); 49 | })(0, -1); 50 | 51 | auto LCA = [&depth, &anc](int u, int v) { 52 | if(depth[u] < depth[v]) 53 | swap(u, v); 54 | for(int k = LG-1; ~k; k--) 55 | if(depth[u]-depth[v] >> k & 1) 56 | u = anc[k][u]; 57 | if(u == v) 58 | return u; 59 | for(int k = LG-1; ~k; k--) 60 | if(anc[k][u] ^ anc[k][v]) 61 | u = anc[k][u], v = anc[k][v]; 62 | return anc[0][u]; 63 | }; 64 | 65 | while(Q--) { 66 | int u, v; cin >> u >> v; 67 | cout << LCA(--u, --v) + 1 << '\n'; 68 | } 69 | } // ~W -------------------------------------------------------------------------------- /CSES/Tree Algorithms/Distance Queries.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 12.02.2021 10:45:31 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | const int64_t DESPACITO = 2e18; 25 | const int INF = 2e9, MOD = 1e9+7; 26 | const int N = 2e5 + 5; 27 | const int LG = 20; 28 | 29 | int main() { 30 | cin.tie(nullptr)->sync_with_stdio(false); 31 | int i, n, Q; 32 | cin >> n >> Q; 33 | vector> g(n); 34 | for(i = 0; i < n-1; i++) { 35 | int u, v; cin >> u >> v; u--, v--; 36 | g[u].pb(v); g[v].pb(u); 37 | } 38 | 39 | array, LG> anc; 40 | for(auto& x: anc) x.assign(n, -1); 41 | 42 | vector depth(n); 43 | Y([&](auto dfs, int v, int p) -> void { 44 | anc[0][v] = p; 45 | for(int k = 1; k < LG; k++) 46 | anc[k][v] = ~anc[k-1][v]? anc[k-1][anc[k-1][v]] : -1; 47 | for(auto& x: g[v]) if(x ^ p) 48 | depth[x] = depth[v] + 1, dfs(x, v); 49 | })(0, -1); 50 | 51 | auto LCA = [&depth, &anc](int u, int v) { 52 | if(depth[u] < depth[v]) 53 | swap(u, v); 54 | for(int k = LG-1; ~k; k--) 55 | if(depth[u]-depth[v] >> k & 1) 56 | u = anc[k][u]; 57 | if(u == v) 58 | return u; 59 | for(int k = LG-1; ~k; k--) 60 | if(anc[k][u] ^ anc[k][v]) 61 | u = anc[k][u], v = anc[k][v]; 62 | return anc[0][u]; 63 | }; 64 | 65 | auto dist = [&depth, &LCA](int u, int v) { 66 | return depth[u] + depth[v] - 2 * depth[LCA(u, v)]; 67 | }; 68 | 69 | while(Q--) { 70 | int u, v; cin >> u >> v; 71 | cout << dist(--u, --v) << '\n'; 72 | } 73 | } // ~W -------------------------------------------------------------------------------- /CSES/Tree Algorithms/Distinct Colors.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 12.02.2021 11:45:27 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | const int64_t DESPACITO = 2e18; 25 | const int INF = 2e9, MOD = 1e9+7; 26 | const int N = 2e5 + 5; 27 | 28 | int main() { 29 | cin.tie(nullptr)->sync_with_stdio(false); 30 | int i, n; 31 | cin >> n; 32 | vector col(n); 33 | for(auto& x: col) cin >> x; 34 | 35 | vector> g(n); 36 | for(i = 0; i < n-1; i++) { 37 | int u, v; cin >> u >> v; u--, v--; 38 | g[u].pb(v); g[v].pb(u); 39 | } 40 | 41 | vector ans(n); 42 | vector> sub(n); 43 | Y([&](auto dfs, int v, int p) -> void { 44 | sub[v].insert(col[v]); 45 | for(auto& x: g[v]) if(x^p) { 46 | dfs(x, v); 47 | if(sz(sub[x]) > sz(sub[v])) 48 | swap(sub[x], sub[v]); 49 | sub[v].merge(sub[x]); 50 | } ans[v] = sz(sub[v]); 51 | })(0, -1); 52 | 53 | for(auto& x: ans) cout << x << ' '; 54 | } // ~W -------------------------------------------------------------------------------- /CSES/Tree Algorithms/Matching.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 19:39:48 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; }; 15 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 16 | 17 | template class Y { 18 | T f; 19 | public: 20 | template explicit Y(U&& f): f(forward(f)) {} 21 | template decltype(auto) operator()(Args&&... args) { 22 | return f(ref(*this), forward(args)...); 23 | } 24 | }; template Y(T) -> Y; 25 | 26 | const int64_t DESPACITO = 2e18; 27 | const int INF = 2e9, MOD = 1e9+7; 28 | const int N = 2e5 + 5; 29 | 30 | int main() { 31 | cin.tie(nullptr)->sync_with_stdio(false); 32 | int i, n; 33 | cin >> n; 34 | vector> g(n); 35 | for(i = 0; i < n-1; i++) { 36 | int u, v; cin >> u >> v; u--, v--; 37 | g[u].pb(v); g[v].pb(u); 38 | } 39 | 40 | vector> dp(n); 41 | Y([&](auto dfs, int v, int p) -> void { 42 | dp[v] = {}; 43 | for(auto& x: g[v]) if(x^p) { 44 | dfs(x, v); 45 | dp[v][0] += dp[x][1]; 46 | chmax(dp[v][1], -dp[x][1] + dp[x][0] + 1); 47 | } dp[v][1] += dp[v][0]; 48 | })(0, -1); 49 | 50 | cout << max(dp[0][0], dp[0][1]); 51 | } // ~W -------------------------------------------------------------------------------- /CSES/Tree Algorithms/Subordinates.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 19:18:21 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | const int64_t DESPACITO = 2e18; 25 | const int INF = 2e9, MOD = 1e9+7; 26 | const int N = 2e5 + 5; 27 | 28 | int main() { 29 | cin.tie(nullptr)->sync_with_stdio(false); 30 | int i, n; 31 | cin >> n; 32 | vector> g(n); 33 | for(i = 1; i < n; i++) { 34 | int p; cin >> p; 35 | g[--p].pb(i); 36 | } 37 | 38 | vector sub(n, 1); 39 | Y([&](auto dfs, int v) -> void { 40 | for(auto& x: g[v]) { 41 | dfs(x); 42 | sub[v] += sub[x]; 43 | } 44 | })(0); 45 | 46 | for(auto& x: sub) 47 | cout << x-1 << ' '; 48 | } // ~W -------------------------------------------------------------------------------- /CSES/Tree Algorithms/Tree Diameter.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 20:15:33 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | const int64_t DESPACITO = 2e18; 25 | const int INF = 2e9, MOD = 1e9+7; 26 | const int N = 2e5 + 5; 27 | 28 | int main() { 29 | cin.tie(nullptr)->sync_with_stdio(false); 30 | int i, n; 31 | cin >> n; 32 | vector> g(n); 33 | for(i = 0; i < n-1; i++) { 34 | int u, v; cin >> u >> v; u--, v--; 35 | g[u].pb(v); g[v].pb(u); 36 | } 37 | 38 | auto bfs = [&] (int root) { 39 | queue q; q.push(root); 40 | vector d(n, -1); d[root] = 0; 41 | while(!q.empty()) { 42 | auto cur = q.front(); q.pop(); 43 | for(auto nxt : g[cur]) { 44 | if(d[nxt] == -1) { 45 | d[nxt] = d[cur] + 1; 46 | q.push(nxt); 47 | } 48 | } 49 | } auto it = max_element(all(d)); 50 | return make_pair(it-d.begin(), *it); 51 | }; 52 | 53 | cout << bfs(bfs(0).first).second; 54 | } // ~W -------------------------------------------------------------------------------- /CSES/Tree Algorithms/Tree Distances I.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 11.02.2021 20:24:44 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | const int64_t DESPACITO = 2e18; 25 | const int INF = 2e9, MOD = 1e9+7; 26 | const int N = 2e5 + 5; 27 | 28 | int main() { 29 | cin.tie(nullptr)->sync_with_stdio(false); 30 | int i, n; 31 | cin >> n; 32 | vector> g(n); 33 | for(i = 0; i < n-1; i++) { 34 | int u, v; cin >> u >> v; u--, v--; 35 | g[u].pb(v); g[v].pb(u); 36 | } 37 | 38 | vector, 2>> dp(n); 39 | Y([&](auto dfs, int v, int p) -> void { 40 | dp[v][0] = dp[v][1] = {0, -1}; 41 | for(auto& x: g[v]) if(x^p) { 42 | dfs(x, v); 43 | array cand = {dp[x][0][0] + 1, x}; 44 | if(cand[0]) 45 | dp[v][1] = cand > dp[v][0]? exchange(dp[v][0], cand) : max(dp[v][1], cand); 46 | } 47 | })(0, -1); 48 | 49 | Y([&](auto dfs, int v, int p) -> void { 50 | for(auto& x: g[v]) if(x^p) { 51 | array cand = {dp[v][!(dp[v][0][1] ^ x)][0] + 1, v}; 52 | dp[x][1] = cand > dp[x][0]? exchange(dp[x][0], cand) : max(dp[x][1], cand); 53 | dfs(x, v); 54 | } 55 | })(0, -1); 56 | 57 | for(i = 0; i < n; i++) 58 | cout << dp[i][0][0] << " \n"[i == n-1]; 59 | } // ~W -------------------------------------------------------------------------------- /CSES/Tree Algorithms/Tree Distances II.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 🍪 thew6rst 3 | 🍪 12.02.2021 10:38:39 4 | **/ 5 | #ifdef W 6 | #include "k_II.h" 7 | #else 8 | #include 9 | using namespace std; 10 | #endif 11 | #define pb emplace_back 12 | #define all(x) x.begin(), x.end() 13 | #define sz(x) static_cast(x.size()) 14 | 15 | template class Y { 16 | T f; 17 | public: 18 | template explicit Y(U&& f): f(forward(f)) {} 19 | template decltype(auto) operator()(Args&&... args) { 20 | return f(ref(*this), forward(args)...); 21 | } 22 | }; template Y(T) -> Y; 23 | 24 | const int64_t DESPACITO = 2e18; 25 | const int INF = 2e9, MOD = 1e9+7; 26 | const int N = 2e5 + 5; 27 | 28 | int main() { 29 | cin.tie(nullptr)->sync_with_stdio(false); 30 | int i, n; 31 | cin >> n; 32 | vector> g(n); 33 | for(i = 0; i < n-1; i++) { 34 | int u, v; cin >> u >> v; u--, v--; 35 | g[u].pb(v); g[v].pb(u); 36 | } 37 | 38 | vector sub(n, 1); 39 | vector dp(n); 40 | Y([&](auto dfs, int v, int p) -> void { 41 | for(auto& x: g[v]) if(x^p) { 42 | dfs(x, v); 43 | sub[v] += sub[x]; 44 | dp[v] += dp[x] + sub[x]; 45 | } 46 | })(0, -1); 47 | 48 | Y([&](auto dfs, int v, int p) -> void { 49 | for(auto& x: g[v]) if(x^p) { 50 | dp[x] += dp[v] - (dp[x] + sub[x]) + n-sub[x]; 51 | dfs(x, v); 52 | } 53 | })(0, -1); 54 | 55 | for(auto& x: dp) cout << x << ' '; 56 | } // ~W -------------------------------------------------------------------------------- /Complexity and Big-O Notation.md: -------------------------------------------------------------------------------- 1 | # Complexity and Big-O Notation 2 | 3 | 4 | Time and space complexity analysis is an important part of problem solving. All competitive programming problems have a time limit and a memory limit. Even if your solution is logically 'correct', it may not meet these requirements. Thus, it is important to be able to estimate the runtime and memory usage of your algorithm to come up with solutions that pass. 5 | 6 | The Big-O notation is used to describe how an algorithm scales with the size of the input. The following are some nice beginner articles on the same: 7 | * [Learning & Understanding Big-O Notation](https://www.topcoder.com/blog/learning-understanding-big-o-notation/) 8 | * [Time and space complexity](https://www.hackerearth.com/practice/basic-programming/complexity-analysis/time-and-space-complexity/tutorial/) 9 | * [Codechef practice problems](https://discuss.codechef.com/t/multiple-choice-questions-related-to-testing-knowledge-about-time-and-space-complexity-of-a-program/17976) 10 | 11 | #### Some things to try/note/remember (some might start to make sense at a later point) 12 | * Try to find the time complexity and space complexity as you write code. With practice you will get better at it. 13 | * Constraints can sometimes give away the expected time complexity of the solution. 14 | * You can assume approximately **108** operations per second to run in time. 15 | * You can use approximately **5 * 107** `int`s worth of memory, be it through a single array of that size (say `arr[10000000]`), or multidimensional arrays (say `arr[10000][1000]`). Be wary that `long long` takes more space than `int`. 16 | * STL/inbuilt functions have their [own time complexity](https://users.cs.northwestern.edu/~riesbeck/programming/c++/stl-summary.html) which you will need to factor in while finding complexity. Also, some STL containers require [more memory](https://pasteboard.co/J6ODpDi.jpg), which may lead to an MLE if you're not careful. -------------------------------------------------------------------------------- /Hello world.md: -------------------------------------------------------------------------------- 1 | #### Hello World 2 | ```c++ 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | int n; 8 | cin >> n; 9 | cout << 2 << " " << "Am I a Watermelon to you" << endl; 10 | return 0; 11 | } 12 | ``` 13 | Try [this](https://codeforces.com/problemset/problem/4/A) problem. 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Hriday G 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /末 Snippets/0-k knapsack.cpp: -------------------------------------------------------------------------------- 1 | /* 0-k Knapsack */ 2 | 3 | /* 4 | Given n items and a knapsack of size s, 5 | i-th item has weight w[i], value v[i] and can be used k[i] times 6 | maximize total value 7 | Time complexity: O(ns) 8 | Algorithms Live Video: https://www.youtube.com/watch?v=U4O3SwDamA4 9 | */ 10 | 11 | int64_t _0kKnapsack(int n, int s, vector& w, vector& v, vector& k) { 12 | auto dist = [](int i, int j, int w) { return abs(i - j) / w; }; 13 | vector dp(s + 1); 14 | for(int i = 0; i < n; i++) { 15 | for(int j, m = s; m > s - w[i] and m >= 0; m--) { // each congruent class (modulo w[i]) 16 | deque maxq; 17 | for(j = m; j >= 0; j -= w[i]) { 18 | while(!maxq.empty() and 19 | dp[j] + dist(j, maxq.back(), w[i]) * v[i] >= dp[maxq.back()]) 20 | maxq.pop_back(); 21 | maxq.push_back(j); 22 | 23 | while(dist(j, maxq.front(), w[i]) >= k[i]) 24 | maxq.pop_front(); 25 | 26 | int x = j + k[i] * w[i]; 27 | if(x <= s) 28 | dp[x] = max(dp[x], dp[maxq.front()] + dist(maxq.front(), x, w[i]) * v[i]); 29 | } 30 | for(j = min(m, j + k[i] * w[i]); j >= 0; j -= w[i]) { 31 | while(!maxq.empty() and maxq.front() >= j) 32 | maxq.pop_front(); 33 | if(!maxq.empty()) 34 | dp[j] = max(dp[j], dp[maxq.front()] + dist(maxq.front(), j, w[i]) * v[i]); 35 | } 36 | } 37 | } 38 | 39 | return *max_element(dp.begin(), dp.end()); 40 | } -------------------------------------------------------------------------------- /末 Snippets/BFS.cpp: -------------------------------------------------------------------------------- 1 | /* Breadth First Search */ 2 | 3 | /* 4 | https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS5%5D%20Do%20you%20understand%20the%20graphity%20of%20this%20situation/%5BEP%201%5D%20Graph%20traversal/%5BPt%202%5D%20BFS.md 5 | */ 6 | 7 | vector> g(n); // adjacency list 8 | 9 | auto bfs = [&](int root) { 10 | queue q; q.push(root); 11 | vector d(n, -1); d[root] = 0; 12 | while(!q.empty()) { 13 | auto cur = q.front(); q.pop(); 14 | for(auto nxt : g[cur]) { 15 | if(d[nxt] == -1) { 16 | d[nxt] = d[cur] + 1; 17 | q.push(nxt); 18 | } 19 | } 20 | } return d; 21 | }; 22 | 23 | // --------------------------------------------------------- 24 | /* BFS 2D */ 25 | 26 | const array dx{1, 0, -1, 0}; 27 | const array dy{0, 1, 0, -1}; 28 | 29 | auto valid = [&](int x, int y) { 30 | return 0 <= x and x < n and 0 <= y and y < m and a[x][y] != '#'; 31 | }; 32 | 33 | auto bfs = [&](int stx, int sty) { 34 | queue> q; 35 | vector> d(n, vector(m, -1)); 36 | q.emplace(stx, sty); d[stx][sty] = 0; 37 | while(!q.empty()) { 38 | auto [curx, cury] = q.front(); q.pop(); 39 | for(int z = 0; z < 4; z++) { 40 | int nx = curx + dx[z]; 41 | int ny = cury + dy[z]; 42 | if(valid(nx, ny) and d[nx][ny] == -1) { 43 | d[nx][ny] = d[curx][cury] + 1; 44 | q.emplace(nx, ny); 45 | } 46 | } 47 | } return d; 48 | }; -------------------------------------------------------------------------------- /末 Snippets/BIT (Fenwick tree).cpp: -------------------------------------------------------------------------------- 1 | /* Binary Indexed Tree (BIT) */ 2 | 3 | // T -> type, ONE -> indexing 4 | template 5 | struct BIT { 6 | int N; vector bit; 7 | BIT() = default; 8 | BIT(int N): N(N), bit(N + 1) {} 9 | 10 | BIT(const vector& a) : N(a.size()), bit(N + 1) { 11 | for(int i = 1; i <= N; i++) { 12 | bit[i] += a[i-1]; 13 | if(i + (i & -i) <= N) 14 | bit[i + (i & -i)] += bit[i]; 15 | } 16 | } 17 | 18 | T query(int i) { 19 | T res = 0; 20 | for(i += !ONE; i; i -= i & -i) 21 | res += bit[i]; 22 | return res; 23 | } 24 | 25 | T query(int l, int r) { 26 | if(l > r) return T(); 27 | return query(r) - query(l - 1); 28 | } 29 | 30 | void update(int i, T val) { 31 | for(i += !ONE; i <= N; i += i & -i) 32 | bit[i] += val; 33 | } 34 | }; -------------------------------------------------------------------------------- /末 Snippets/Binary exponentiation.cpp: -------------------------------------------------------------------------------- 1 | /* Binary Exponentiation */ 2 | 3 | /* 4 | https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS2%5D%20Primal%20proficiency/%5BEP%205%5D%20Binary%20Exponentiation.md 5 | */ 6 | 7 | template 8 | T expo(T A, int64_t B) { // A^{B} 9 | T res{1}; while(B) { 10 | if(B & 1) res = res * A; 11 | B >>= 1; A = A * A; 12 | } return res; 13 | } 14 | -------------------------------------------------------------------------------- /末 Snippets/Binary search.cpp: -------------------------------------------------------------------------------- 1 | /* Binary Search */ 2 | 3 | /* 4 | https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS3%5D%202P%20or%20not%20to%202P%2C%20No%20wait%20isn%27t%20this%20just%20bs/%5BEP%203%5D%20Binary%20search.md 5 | */ 6 | 7 | auto check = [&](int x) { 8 | // ... 9 | return true; 10 | }; 11 | 12 | auto binarySearch = [&](int low, int high) { 13 | while(low <= high) { 14 | int mid = low + high >> 1; 15 | if(check(mid)) low = mid + 1; // Assuming TT...TFF...F 16 | else high = mid - 1; 17 | } return high; // return low for first occurrence of False, high for last occurrence of True 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /末 Snippets/Closest pair of points.cpp: -------------------------------------------------------------------------------- 1 | /* Closest pair of points */ 2 | 3 | /* 4 | https://cp-algorithms.com/geometry/nearest_points.html 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | const int N = 2e5 + 5; 10 | 11 | struct point { 12 | int x, y, id; 13 | }; 14 | 15 | pair ans; 16 | int64_t min_val = 1e18; 17 | vector a; 18 | 19 | auto update = [] (const point& p, const point& q) { 20 | int64_t dist = 1ll*(p.x-q.x)*(p.x-q.x) + 1ll*(p.y-q.y)*(p.y-q.y); 21 | if(dist < min_val) 22 | min_val = dist, ans = make_pair(p.id, q.id); 23 | }; 24 | 25 | void recur(int l, int r) { 26 | int i, j; 27 | if(r-l <= 3) { 28 | sort(a.begin()+l, a.begin()+r, [](const point& A, const point& B) { 29 | return A.y == B.y? A.x < B.x : A.y < B.y; 30 | }); 31 | for(i = l; i < r; i++) 32 | for(j = l; j < i; j++) 33 | update(a[i], a[j]); 34 | return; 35 | } 36 | 37 | int m = (l+r)/2; 38 | recur(l, m); recur(m, r); 39 | 40 | static point tmp[N]; 41 | merge(a.begin()+l, a.begin()+m, a.begin()+m, a.begin()+r, tmp, 42 | [](const point& A, const point& B) { return A.y == B.y? A.x < B.x : A.y < B.y; }); 43 | 44 | copy(tmp, tmp+r-l, a.begin()+l); 45 | 46 | int top = -1; 47 | for(i = l; i < r; i++) { 48 | if(abs(a[i].x-a[m].x) >= min_val) continue; 49 | for(j = top; ~j and a[i].y-tmp[j].y < min_val; j--) 50 | update(a[i], a[j]); 51 | tmp[++top] = a[i]; 52 | } 53 | } 54 | 55 | int32_t main() { 56 | int i, n; 57 | cin >> n; a.resize(n); 58 | for(i = 0; i < n; i++) 59 | cin >> a[i].x >> a[i].y, a[i].id = i; 60 | 61 | sort(a.begin(), a.end(), [](const point& A, const point& B) { 62 | return A.x == B.x? A.y < B.y : A.x < B.x; 63 | }); 64 | 65 | recur(0, n); 66 | double dist = sqrt(min_val); 67 | cout << fixed << setprecision(4); 68 | cout << dist << '\n' << ans.first << ' ' << ans.second; 69 | 70 | return 0; 71 | } -------------------------------------------------------------------------------- /末 Snippets/DSU.cpp: -------------------------------------------------------------------------------- 1 | /* Disjoint Set Union or Union Find */ 2 | 3 | /* 4 | https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS5%5D%20Do%20you%20understand%20the%20graphity%20of%20this%20situation/%5BEP%203%5D%20Spanning%20Trees/%5BPt%201%5D%20Disjoint%20Set%20Union%20%28Union%20Find%29.md 5 | */ 6 | 7 | struct DSU { 8 | int n, components; 9 | vector data, rootID, roots; 10 | 11 | DSU(int n): n(n), components(n), data(n + 1, -1), rootID(n + 1, -1) {} 12 | 13 | int par(int x) { 14 | return data[x] < 0? x : data[x] = par(data[x]); 15 | } 16 | // data[x] = -ve size of component if root, else parent of x (>= 0) 17 | int SZ(int x) { 18 | return -data[par(x)]; 19 | } 20 | 21 | bool merge(int x, int y) { 22 | x = par(x); y = par(y); 23 | if(x == y) return false; 24 | if(-data[x] < -data[y]) swap(x, y); 25 | data[x] += data[y]; data[y] = x; components--; 26 | return true; 27 | } 28 | 29 | // call only once 30 | void getRoots() { 31 | roots.reserve(components); 32 | for(int i = 0; i < n; i++) { 33 | if(data[i] < 0) { 34 | rootID[i] = roots.size(); 35 | roots.push_back(i); 36 | } 37 | } 38 | } 39 | }; 40 | 41 | 42 | // ---------------------------------------------- 43 | /* v2 */ 44 | 45 | vector par(n + 1, -1); // par[x] = -ve size of component if root, else parent of x (>= 0) 46 | 47 | auto get_par = [&par](int A) { 48 | while(par[A] >= 0) { 49 | if(par[par[A]] >= 0) 50 | par[A] = par[par[A]]; 51 | A = par[A]; 52 | } return A; 53 | }; 54 | 55 | auto merge = [&get_par, &par](int A, int B) { 56 | A = get_par(A); B = get_par(B); 57 | if(A == B) return false; 58 | if(-par[A] < -par[B]) swap(A, B); 59 | par[A] += par[B]; par[B] = A; 60 | return true; 61 | }; 62 | -------------------------------------------------------------------------------- /末 Snippets/Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | /* Dijkstra's */ 2 | 3 | /* 4 | https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS5%5D%20Do%20you%20understand%20the%20graphity%20of%20this%20situation/%5BEP%202%5D%20Shortest%20paths/%5BPt%202%5D%20Dijkstra%27s.md 5 | */ 6 | 7 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 8 | 9 | vector> g(n); // adjacency list 10 | vector d(n, INF); 11 | vector par(n, -1); 12 | 13 | auto dijkstra = [&] (int root) { 14 | struct state { 15 | int v; int64_t dist; 16 | state(int v, int64_t dist): v(v), dist(dist) {} 17 | bool operator<(const state& o) const { 18 | return dist > o.dist; 19 | } 20 | }; 21 | 22 | priority_queue pq; 23 | pq.emplace(root, d[root] = 0); 24 | 25 | while(!pq.empty()) { 26 | state top = pq.top(); pq.pop(); 27 | if(top.dist > d[top.v]) continue; 28 | for(auto& [to, w]: g[top.v]) 29 | if(chmin(d[to], top.dist + w)) 30 | pq.emplace(to, d[to]), par[to] = top.v; 31 | } 32 | 33 | }; -------------------------------------------------------------------------------- /末 Snippets/Edge_t.cpp: -------------------------------------------------------------------------------- 1 | /* Edge struct */ 2 | 3 | struct edge_t { 4 | int u{-1}, v{-1}; int64_t w{0}; 5 | edge_t() = default; 6 | edge_t(int u, int v, int64_t w = 0) : u(u), v(v), w(w) {} 7 | bool operator<(const edge_t& other) { return w < other.w; } 8 | friend ostream& operator<<(ostream& os, const edge_t& e) { os << e.u << ' ' << e.v << ' ' << e.w; return os; } 9 | }; 10 | 11 | /* vector edges; 12 | edges.emplace_back(2, 3, 123456); 13 | edges.emplace_back(1, 2, 134); 14 | sort(edges.begin(), edges.end()); 15 | */ 16 | -------------------------------------------------------------------------------- /末 Snippets/Euler Circuit (directed).cpp: -------------------------------------------------------------------------------- 1 | /* Eulerian Circuit (directed) */ 2 | // Hierholzer’s Algorithm 3 | 4 | /* 5 | CPH: 6 | https://cses.fi/book/book.pdf#page=183 7 | Hello world: 8 | https://cses.fi/problemset/task/1693 9 | */ 10 | 11 | vector indeg(n), outdeg(n); 12 | vector> g(n); 13 | for(i = 0; i < m; i++) { 14 | int u, v; cin >> u >> v; 15 | outdeg[--u]++; indeg[--v]++; 16 | g[u].push_back(v); 17 | } 18 | 19 | bool bad = false; 20 | for(i = 1; i < n-1; i++) 21 | bad |= outdeg[i] ^ indeg[i]; 22 | 23 | bad |= outdeg[0]-indeg[0] ^ 1; 24 | bad |= indeg[n-1]-outdeg[n-1] ^ 1; 25 | 26 | if(bad) 27 | // IMPOSSIBLE 28 | 29 | vector tour; 30 | tour.reserve(m+1); 31 | Y([&](auto dfs, int v) -> void { 32 | while(outdeg[v]-- > 0) 33 | dfs(g[v][outdeg[v]]); 34 | tour.push_back(v); 35 | })(0); // dfs(0); 36 | 37 | for(i = 0; i < n; i++) 38 | if(outdeg[i] > 0) 39 | // IMPOSSIBLE 40 | 41 | reverse(tour.begin(), tour.end()); 42 | -------------------------------------------------------------------------------- /末 Snippets/Euler Circuit (undirected).cpp: -------------------------------------------------------------------------------- 1 | /* Eulerian Circuit (undirected) */ 2 | // Hierholzer’s Algorithm 3 | 4 | /* 5 | CPH: 6 | https://cses.fi/book/book.pdf#page=183 7 | Hello world: 8 | https://cses.fi/problemset/task/1691 9 | */ 10 | 11 | struct edge_t { 12 | int u{-1}, v{-1}; bool done{false}; 13 | edge_t() = default; 14 | edge_t(int u, int v) : u(u), v(v) {} 15 | }; 16 | 17 | vector deg(n); 18 | vector edges; 19 | edges.reserve(m); 20 | vector> g(n); 21 | 22 | for(i = 0; i < m; i++) { 23 | int u, v; cin >> u >> v; 24 | deg[--u]++; deg[--v]++; 25 | edges.emplace_back(u, v); 26 | g[u].push_back(&edges.back()); 27 | g[v].push_back(&edges.back()); 28 | } 29 | 30 | bool bad = false; 31 | for(i = 0; i < n; i++) 32 | bad |= deg[i] & 1; 33 | 34 | if(bad) 35 | // IMPOSSIBLE 36 | 37 | vector tour; 38 | tour.reserve(m+1); 39 | Y([&](auto dfs, int v) -> void { 40 | while(deg[v]-- > 0) { 41 | auto e = g[v][deg[v]]; 42 | if(!e->done) 43 | e->done = true, dfs(e->u ^ e->v ^ v); 44 | } tour.push_back(v); 45 | })(0); // dfs(0); 46 | 47 | for(i = 0; i < n; i++) 48 | if(deg[i] > 0) 49 | // IMPOSSIBLE 50 | 51 | reverse(tour.begin(), tour.end()); 52 | -------------------------------------------------------------------------------- /末 Snippets/Extended Euclidean algorithm.cpp: -------------------------------------------------------------------------------- 1 | /* Extended Euclidean algorithm and Linear Diophantine Equation solver */ 2 | 3 | /* 4 | https://cp-algorithms.com/algebra/extended-euclid-algorithm.html 5 | https://cp-algorithms.com/algebra/linear-diophantine-equation.html 6 | */ 7 | 8 | // ax + by = gcd(a, b) : returns {x, y, g} 9 | auto extended = [](int64_t a, int64_t b) { 10 | int64_t x = 1, y = 0, prvx = 0, prvy = 1; 11 | while(b) { 12 | int64_t q = a / b; 13 | tie(x, prvx) = make_tuple(prvx, x - q * prvx); 14 | tie(y, prvy) = make_tuple(prvy, y - q * prvy); 15 | tie(a, b) = make_tuple(b, a - q * b); 16 | } return make_tuple(x, y, a); 17 | }; 18 | 19 | // ax + by = c : returns {true/false, x, y, g} 20 | auto diophantine = [&extended](int64_t a, int64_t b, int64_t c) { 21 | if(!a and !b) return make_tuple(!c, 42LL, 17LL, 0LL); 22 | auto [x, y, g] = extended(a, b); 23 | return make_tuple(!(c % g), c / g * x, c / g * y, abs(g)); 24 | }; 25 | 26 | // x = x0 + λ b/g 27 | // y = y0 - λ a/g 28 | auto diophantine_range = [&extended] (int64_t a, int64_t b, int64_t c, 29 | int64_t lx, int64_t rx, int64_t ly, int64_t ry) { 30 | assert(a and b); 31 | 32 | auto [x, y, g] = extended(a, b); 33 | x *= c / g; y *= c / g; g = abs(g); 34 | a /= g; b /= g; 35 | 36 | if(c % g) return 0LL; 37 | 38 | int sign_a = a > 0 ? +1 : -1; 39 | int sign_b = b > 0 ? +1 : -1; 40 | 41 | auto shift = [&x, &y, &a, &b](int64_t cnt) { 42 | x += cnt * b; 43 | y -= cnt * a; 44 | }; 45 | 46 | shift((lx - x) / b); 47 | if(x < lx) shift(sign_b); 48 | if(x > rx) return 0LL; 49 | int64_t lx1 = x; 50 | 51 | shift((rx - x) / b); 52 | if(x > rx) shift(-sign_b); 53 | int64_t rx1 = x; 54 | 55 | shift(-(ly - y) / a); 56 | if(y < ly) shift(-sign_a); 57 | if(y > ry) return 0LL; 58 | int64_t lx2 = x; 59 | 60 | shift(-(ry - y) / a); 61 | if(y > ry) shift(sign_a); 62 | int64_t rx2 = x; 63 | 64 | if(lx2 > rx2) swap(lx2, rx2); 65 | int64_t _lx = max(lx1, lx2); 66 | int64_t _rx = min(rx1, rx2); 67 | 68 | if(_lx > _rx) return 0LL; 69 | return (_rx - _lx) / abs(b) + 1; 70 | }; -------------------------------------------------------------------------------- /末 Snippets/Factorization.cpp: -------------------------------------------------------------------------------- 1 | /* Prime factorization */ 2 | /* [neal](https://codeforces.com/profile/neal) orz */ 3 | 4 | // Prime factorizes n in worst case O(sqrt n). 5 | vector> prime_factorize(int64_t n) { 6 | assert(n >= 1); 7 | vector> result; 8 | 9 | for(int64_t p = 2; p * p <= n; p++) 10 | if(n % p == 0) { 11 | result.emplace_back(p, 0); 12 | 13 | do { 14 | n /= p; 15 | result.back().second++; 16 | } while(n % p == 0); 17 | } 18 | 19 | if(n > 1) 20 | result.emplace_back(n, 1); 21 | 22 | return result; 23 | } 24 | 25 | // This covers up to 2^64. See http://oeis.org/A066150 and http://oeis.org/A036451 26 | const int FACTORS_MAX = 185000; 27 | 28 | vector generate_factors(const vector> &prime_factors, bool sorted = false) { 29 | static int64_t buffer[FACTORS_MAX]; 30 | int product = 1; 31 | 32 | for(auto &pf : prime_factors) 33 | product *= pf.second; 34 | 35 | vector factors = {1}; 36 | factors.reserve(product); 37 | 38 | for(auto &pf : prime_factors) { 39 | int64_t p = pf.first; 40 | int exponent = pf.second; 41 | int before_size = int(factors.size()); 42 | 43 | for(int i = 0; i < exponent * before_size; i++) 44 | factors.push_back(factors[factors.size() - before_size] * p); 45 | 46 | if(sorted && factors[before_size - 1] > p) 47 | for(int section = before_size; section < int(factors.size()); section *= 2) 48 | for(int i = 0; i + section < int(factors.size()); i += 2 * section) { 49 | int length = min(2 * section, int(factors.size()) - i); 50 | merge(factors.begin() + i, factors.begin() + i + section, factors.begin() + i + section, factors.begin() + i + length, buffer); 51 | copy(buffer, buffer + length, factors.begin() + i); 52 | } 53 | } 54 | return factors; 55 | } 56 | -------------------------------------------------------------------------------- /末 Snippets/FileIO (freopen).cpp: -------------------------------------------------------------------------------- 1 | /* File io using freopen */ 2 | 3 | freopen("input.txt", "r", stdin); 4 | freopen("output.txt", "w", stdout); 5 | 6 | cin >> x; 7 | cout << x; -------------------------------------------------------------------------------- /末 Snippets/Floyd Warshall.cpp: -------------------------------------------------------------------------------- 1 | /* Floyd-Warshall's all pair shortest paths */ 2 | 3 | /* 4 | https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS5%5D%20Do%20you%20understand%20the%20graphity%20of%20this%20situation/%5BEP%202%5D%20Shortest%20paths/%5BPt%203%5D%20Floyd-Warshall.md 5 | */ 6 | 7 | auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; }; 8 | 9 | vector d(n, vector(n, INF)), path(n, vector(n, -1)); 10 | for(auto [u, v, w]: edges) 11 | d[u][v] = w, path[u][v] = v; 12 | // d[i][i] = 0; 13 | 14 | for(int k = 0; k < n; k++) 15 | for(int i = 0; i < n; i++) 16 | for(int j = 0; j < n; j++) 17 | if(chmin(d[i][j], d[i][k] + d[k][j])) 18 | path[i][j] = path[i][k]; 19 | 20 | vector ans{ u }; 21 | while(u ^ v) { 22 | u = path[u][v]; 23 | ans.push_back(u); 24 | } -------------------------------------------------------------------------------- /末 Snippets/GP hash table (unordered map alternative).cpp: -------------------------------------------------------------------------------- 1 | /* GP hash table, an alternative to unordered_map w/ custom hash */ 2 | 3 | /* 4 | - pbds gp hash table (better than unordered_map) 5 | https://codeforces.com/blog/entry/60737 6 | - custom hash, blowing up unordered_map 7 | https://codeforces.com/blog/entry/62393 8 | */ 9 | 10 | #include 11 | namespace Hashing { 12 | using hash_t = pair; 13 | static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 14 | 15 | // Custom hash using splitmix64 (https://codeforces.com/blog/entry/62393) 16 | struct custom_hash { 17 | static uint64_t splitmix64(uint64_t x) { 18 | x += 0x9e3779b97f4a7c15; 19 | x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; 20 | x = (x ^ (x >> 27)) * 0x94d049bb133111eb; 21 | return x ^ (x >> 31); 22 | } 23 | size_t operator()(uint64_t x) const { 24 | return splitmix64(x + FIXED_RANDOM); 25 | } 26 | size_t operator()(const hash_t& x) const { 27 | return splitmix64(FIXED_RANDOM + x.second) 28 | ^ (splitmix64(FIXED_RANDOM + x.first) << 1); 29 | } 30 | }; 31 | 32 | // gp_hash_table benchmarks vs unordered_map (https://codeforces.com/blog/entry/60737) 33 | template 34 | using hash_map = __gnu_pbds::gp_hash_table; 35 | 36 | template 37 | using hash_set = hash_map; 38 | } -------------------------------------------------------------------------------- /末 Snippets/KMP.cpp: -------------------------------------------------------------------------------- 1 | /* KMP */ 2 | 3 | /* 4 | https://discuss.codechef.com/t/tutorial-prefix-function-pattern-matching-supposedly-kmp/67531 5 | https://cp-algorithms.com/string/prefix-function.html 6 | https://www.youtube.com/watch?v=nJbNe0Yzjhw 7 | See also: Z algo 8 | */ 9 | 10 | // pi[i] is the longest proper prefix 11 | // that is a suffix ending at position i 12 | // abcd.abceab 13 | // 0000 123012 14 | auto generate_pi = [&](const string& s) { 15 | // s = (pattern + '#' + text) 16 | int n = s.size(); 17 | vector pi(n); 18 | for(i = 1; i < n; i++) { 19 | int p = pi[i-1]; 20 | while(p and s[i] != s[p]) p = pi[p-1]; 21 | pi[i] = p + (s[i] == s[p]); 22 | } 23 | return pi; 24 | }; 25 | /* Getting all lengths ending at x-th pos 26 | while(pi[x]) { 27 | add pi[x] to ans 28 | x = pi[x]-1 29 | } 30 | Number of occurrences of each prefix 31 | for i from '#' to end 32 | pref[pi[i]]++ 33 | for i = n to 1 34 | pref[pi[i-1]] += pref[i] 35 | 36 | Check if it is periodic 37 | auto check = [](int len, int pi) { 38 | return pi and len % (len - pi) == 0; 39 | }; 40 | check(n, pi[n-1]) == true 41 | */ 42 | -------------------------------------------------------------------------------- /末 Snippets/LCA using Binary Lifting (O(nlogn) \ O(logn)).cpp: -------------------------------------------------------------------------------- 1 | /* Lowest Common Ancestor using Binary lifting */ 2 | 3 | /* 4 | precomp: O(nlogn) 5 | query: O(logn) 6 | memory: O(nlogn) 7 | 8 | https://cp-algorithms.com/graph/lca_binary_lifting.html 9 | https://cses.fi/book/book.pdf#page=177 10 | https://www.topcoder.com/thrive/articles/Range%20Minimum%20Query%20and%20Lowest%20Common%20Ancestor 11 | */ 12 | 13 | const int LG = 18; 14 | vector depth(n); 15 | array, LG> anc; 16 | for(auto& x: anc) x.assign(n, -1); 17 | 18 | Y([&](auto dfs, int v, int p) -> void { 19 | anc[0][v] = p; 20 | for(int k = 1; k < LG; k++) 21 | if(~anc[k-1][v]) anc[k][v] = anc[k-1][anc[k-1][v]]; 22 | for(auto& x: g[v]) if(x^p) { 23 | depth[x] = depth[v] + 1; dfs(x, v); 24 | } 25 | })(0, -1); // dfs(0, -1); 26 | 27 | auto LCA = [&](int u, int v) { 28 | if(depth[u] < depth[v]) swap(u, v); 29 | for(int z = 0; z < LG; z++) 30 | if(depth[u]-depth[v] >> z & 1) u = anc[z][u]; 31 | if(u == v) return u; 32 | for(int z = LG-1; ~z; z--) 33 | if(anc[z][u] ^ anc[z][v]) 34 | u = anc[z][u], v = anc[z][v]; 35 | return anc[0][u]; 36 | }; 37 | 38 | -------------------------------------------------------------------------------- /末 Snippets/LIS.cpp: -------------------------------------------------------------------------------- 1 | /* Longest increasing subsequence */ 2 | 3 | /* 4 | https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS4%5D%20Boohoo~%20It%27s%20dp%20time/%5BEP%205%5D%20LIS.md 5 | */ 6 | 7 | template 8 | int LIS(const vector& v) { 9 | vector lis; lis.reserve(v.size()); 10 | for(auto& x: v) { 11 | auto it = lower_bound(lis.begin(), lis.end(), x); // upper_bound for non strictly increasing 12 | if(it == lis.end()) lis.push_back(x); 13 | else *it = x; 14 | } return lis.size(); 15 | } 16 | 17 | 18 | // Retrieve indices 19 | template 20 | vector LIS(const vector& v) { 21 | vector lis, path(v.size(), -1); lis.reserve(v.size()); 22 | for(int z = 0; z < v.size(); z++) { 23 | auto it = lower_bound(lis.begin(), lis.end(), z, [&v](int A, int B) { return v[A] < v[B]; }); // upper_bound for non strictly increasing 24 | if(it != lis.begin()) path[z] = *prev(it); 25 | if(it == lis.end()) lis.push_back(z); 26 | else *it = z; 27 | } 28 | int cur = lis.back(); 29 | vector res; res.reserve(lis.size()); 30 | while(~cur) res.push_back(cur), cur = path[cur]; 31 | return reverse(res.begin(), res.end()), res; 32 | } 33 | -------------------------------------------------------------------------------- /末 Snippets/Lambda comparators.cpp: -------------------------------------------------------------------------------- 1 | /* Sets, priority queues & sorting vectors with custom comparators */ 2 | 3 | vector> v; 4 | sort(v.begin(), v.end(), [](const auto& A, const auto& B) { 5 | // ... 6 | // for pairs 7 | return A.second == B.second? 8 | A.first < B.first : A.second < B.second; 9 | }); 10 | 11 | 12 | // STL set and priority_queue comparators 13 | auto cmp = [](const auto& A, const auto& B) { 14 | return A < B; 15 | }; 16 | 17 | set s(cmp); 18 | priority_queue, decltype(cmp)> pq(cmp); 19 | 20 | -------------------------------------------------------------------------------- /末 Snippets/MST (Kruskal's algo).cpp: -------------------------------------------------------------------------------- 1 | /* Minimum Spanning Tree - Kruskal's Algorithm */ 2 | 3 | /* 4 | https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS5%5D%20Do%20you%20understand%20the%20graphity%20of%20this%20situation/%5BEP%203%5D%20Spanning%20Trees/%5BPt%202%5D%20Kruskal%27s%20MST.md 5 | */ 6 | 7 | struct edge_t { 8 | int u, v, w; 9 | edge_t(int u, int v, int w) : u(u), v(v), w(w) {} 10 | bool operator<(const edge_t& other) { return w < other.w; } 11 | friend ostream& operator<<(ostream& os, edge_t& e) { os << e.u << ' ' << e.v << ' ' << e.w; return os; } 12 | }; 13 | 14 | vector par(n), sz_(n, 1); 15 | iota(par.begin(), par.end(), 0); 16 | 17 | auto getpar = [&] (int x) { 18 | int pp = x; 19 | while(par[pp] != pp) 20 | pp = par[pp]; 21 | while(par[x] != x) { 22 | int z = par[x]; 23 | par[x] = pp; 24 | x = z; 25 | } 26 | return pp; 27 | }; 28 | 29 | auto merge = [&] (int x, int y) { 30 | x = getpar(x); 31 | y = getpar(y); 32 | if (x == y) return false; 33 | if (sz_[x] < sz_[y]) swap(x, y); 34 | par[y] = x, sz_[x] += sz_[y]; 35 | return true; 36 | }; 37 | 38 | vector edges, ans; 39 | // ... 40 | sort(edges.begin(), edges.end()); 41 | int cost = 0; 42 | 43 | for(auto& e: edges) 44 | if(merge(e.u, e.v)) 45 | cost += e.w, ans.push_back(e); 46 | 47 | -------------------------------------------------------------------------------- /末 Snippets/MST (Prim's algo).cpp: -------------------------------------------------------------------------------- 1 | /* Minimum Spanning Tree - Prim's Algorithm */ 2 | 3 | /* 4 | https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS5%5D%20Do%20you%20understand%20the%20graphity%20of%20this%20situation/%5BEP%203%5D%20Spanning%20Trees/%5BPt%203%5D%20Prim%27s%20MST.md 5 | */ 6 | 7 | int n, m, inedgewt[N], parent[N]; 8 | vector g[N], tree[N]; 9 | vector vis; 10 | 11 | for(i = 0; i < m; i++) { 12 | int u, v, w; 13 | cin >> u >> v >> w; 14 | u--, v--; 15 | g[u].emplace_back(v, w); 16 | g[v].emplace_back(u, w); 17 | } 18 | 19 | vis.resize(n); 20 | for(i = 0; i < n; i++) 21 | inedgewt[i] = INF; 22 | 23 | auto cmp = [] (const pii A, const pii B) { 24 | if(A.ff == B.ff) return A.ss < B.ss; 25 | return A.ff < B.ff; // comparing 26 | }; 27 | 28 | auto primsMST = [&] (int root) { 29 | set s(cmp); 30 | s.ins({0, root}); 31 | 32 | int cost = 0; 33 | inedgewt[root] = 0; 34 | parent[root] = -1; 35 | 36 | while(!s.empty()) { 37 | auto [wt, cur] = *s.begin(); 38 | s.erase(s.begin()); 39 | 40 | vis[cur] = 1; 41 | cost += wt; 42 | if(~parent[cur]) { 43 | tree[cur].emplace_back(parent[cur], wt); 44 | tree[parent[cur]].emplace_back(cur, wt); 45 | } 46 | 47 | for(auto [to, newwt] : g[cur]) { 48 | if(vis[to]) 49 | continue; 50 | if(inedgewt[to] > newwt) { // comparing 51 | s.erase({inedgewt[to], to}); 52 | inedgewt[to] = newwt; 53 | s.ins({inedgewt[to], to}); 54 | parent[to] = cur; 55 | } 56 | } 57 | } 58 | return cost; 59 | }; -------------------------------------------------------------------------------- /末 Snippets/Manachers.cpp: -------------------------------------------------------------------------------- 1 | /* Manacher's algorithm to find all palindromic substrings in O(n) */ 2 | 3 | /* 4 | CP algorithms: 5 | https://cp-algorithms.com/string/manacher.html 6 | 7 | Problems: 8 | https://www.codechef.com/problems/PALIN3 9 | https://codeforces.com/contest/1326/problem/D2 10 | https://codeforces.com/contest/1080/problem/E 11 | https://open.kattis.com/problems/palindromes 12 | */ 13 | 14 | auto manachers = [&] (const string& s) { 15 | // a b c b a a b b 16 | // 0 0 0 0 0 2 0 1 -- even length stores len/2 17 | // 1 1 3 1 1 1 1 1 -- odd length stores (len+1)/2 18 | int n = s.size(); 19 | vector even(n), odd(n); 20 | for(int z = 0, l = 0, r = -1; z < n; z++) { 21 | int k = (z > r) ? 1 : min(odd[l + r - z], r - z + 1); 22 | while(0 <= z - k and z + k < n and s[z - k] == s[z + k]) k++; 23 | odd[z] = k--; 24 | if(z + k > r) l = z - k, r = z + k; 25 | } 26 | for(int z = 0, l = 0, r = -1; z < n; z++) { 27 | int k = (z > r) ? 0 : min(even[l + r - z + 1], r - z + 1); 28 | while(0 <= z - k - 1 and z + k < n and s[z - k - 1] == s[z + k]) k++; 29 | even[z] = k--; 30 | if(z + k > r) l = z - k - 1, r = z + k; 31 | } 32 | return make_pair(even, odd); 33 | }; 34 | -------------------------------------------------------------------------------- /末 Snippets/Mo's Algorithm/Mo's algorithm on trees (weighted edges).cpp: -------------------------------------------------------------------------------- 1 | /* Mo's algorithm on trees with weighted nodes */ 2 | 3 | /* 4 | Blog: 5 | https://codeforces.com/blog/entry/43230 6 | https://codeforces.com/blog/entry/81716 7 | */ 8 | 9 | vector depth(n), tin(n), tout(n), id(n << 1), parw(n); 10 | array, LG> anc; 11 | for(auto& x: anc) x.assign(n, -1); 12 | 13 | Y([&, t = 0](auto dfs, int v, int p) mutable -> void { 14 | id[tin[v] = t++] = v; 15 | anc[0][v] = p; 16 | for(int k = 1; k < LG; k++) 17 | if(~anc[k-1][v]) anc[k][v] = anc[k-1][anc[k-1][v]]; 18 | for(auto& x: g[v]) if(x ^ p) { 19 | depth[x] = depth[v] + 1; 20 | parw[x] = w; dfs(x, v); 21 | } 22 | id[tout[v] = t++] = v; 23 | })(0, -1); 24 | 25 | auto LCA = [&](int u, int v) { 26 | if(depth[u] < depth[v]) swap(u, v); 27 | for(int z = 0; z < LG; z++) 28 | if(depth[u]-depth[v] >> z & 1) u = anc[z][u]; 29 | if(u == v) return u; 30 | for(int z = LG-1; ~z; z--) 31 | if(anc[z][u] ^ anc[z][v]) 32 | u = anc[z][u], v = anc[z][v]; 33 | return anc[0][u]; 34 | }; 35 | 36 | vector queries; 37 | queries.reserve(Q); 38 | for(i = 0; i < Q; i++) { 39 | int u, v; cin >> u >> v; 40 | if(tin[--u] > tin[--v]) swap(u, v); 41 | queries.emplace_back(u == LCA(u, v)? tin[u] + 1 : tout[u], tin[v] + 1, i); 42 | } 43 | 44 | sort(queries.begin(), queries.end()); 45 | 46 | // [l, r) 47 | int l = 0, r = 0; 48 | int64_t cur = 0; 49 | vector active(n), cnt(n); 50 | 51 | auto toggle = [&](int v) { 52 | if(active[v] and !--cnt[a[v]]) cur--; 53 | else if(!active[v] and !cnt[a[v]]++) cur++; 54 | active[v] ^= 1; 55 | }; 56 | 57 | vector ans(Q); 58 | for(auto& q: queries) { 59 | while(l > q.l) 60 | toggle(id[--l]); 61 | while(r < q.r) 62 | toggle(id[r++]); 63 | while(l < q.l) 64 | toggle(id[l++]); 65 | while(r > q.r) 66 | toggle(id[--r]); 67 | 68 | if(r <= l) continue; 69 | 70 | ans[q.idx] = cur; 71 | } -------------------------------------------------------------------------------- /末 Snippets/Mo's Algorithm/Mo's algorithm on trees (weighted nodes).cpp: -------------------------------------------------------------------------------- 1 | /* Mo's algorithm on trees with weighted nodes */ 2 | 3 | /* 4 | Blog: 5 | https://codeforces.com/blog/entry/43230 6 | https://codeforces.com/blog/entry/81716 7 | */ 8 | 9 | vector depth(n), tin(n), tout(n), id(n << 1); 10 | array, LG> anc; 11 | for(auto& x: anc) x.assign(n, -1); 12 | 13 | Y([&, t = 0](auto dfs, int v, int p) mutable -> void { 14 | id[tin[v] = t++] = v; 15 | anc[0][v] = p; 16 | for(int k = 1; k < LG; k++) 17 | if(~anc[k-1][v]) anc[k][v] = anc[k-1][anc[k-1][v]]; 18 | for(auto& x: g[v]) if(x ^ p) { 19 | depth[x] = depth[v] + 1; dfs(x, v); 20 | } 21 | id[tout[v] = t++] = v; 22 | })(0, -1); 23 | 24 | auto LCA = [&](int u, int v) { 25 | if(depth[u] < depth[v]) swap(u, v); 26 | for(int z = 0; z < LG; z++) 27 | if(depth[u]-depth[v] >> z & 1) u = anc[z][u]; 28 | if(u == v) return u; 29 | for(int z = LG-1; ~z; z--) 30 | if(anc[z][u] ^ anc[z][v]) 31 | u = anc[z][u], v = anc[z][v]; 32 | return anc[0][u]; 33 | }; 34 | 35 | vector queries; 36 | queries.reserve(Q); 37 | for(i = 0; i < Q; i++) { 38 | int u, v; cin >> u >> v; 39 | if(tin[--u] > tin[--v]) 40 | swap(u, v); 41 | int lca = LCA(u, v); 42 | queries.emplace_back(u == lca? tin[u] : tout[u], tin[v] + 1, lca, i); 43 | } 44 | 45 | sort(queries.begin(), queries.end()); 46 | 47 | // [l, r) 48 | int l = 0, r = 0; 49 | int64_t cur = 0; 50 | vector active(n), cnt(n); 51 | 52 | auto toggle = [&](int v) { 53 | if(active[v] and !--cnt[a[v]]) cur--; 54 | else if(!active[v] and !cnt[a[v]]++) cur++; 55 | active[v] ^= 1; 56 | }; 57 | 58 | vector ans(Q); 59 | for(auto& q: queries) { 60 | while(l > q.l) 61 | toggle(id[--l]); 62 | while(r < q.r) 63 | toggle(id[r++]); 64 | while(l < q.l) 65 | toggle(id[l++]); 66 | while(r > q.r) 67 | toggle(id[--r]); 68 | 69 | if(r <= l) continue; 70 | 71 | if(id[q.l] ^ q.lca and id[q.r - 1] ^ q.lca) 72 | toggle(q.lca); 73 | 74 | ans[q.idx] = cur; 75 | 76 | if(id[q.l] ^ q.lca and id[q.r - 1] ^ q.lca) 77 | toggle(q.lca); 78 | } -------------------------------------------------------------------------------- /末 Snippets/Mo's Algorithm/Mo's algorithm with updates.cpp: -------------------------------------------------------------------------------- 1 | /* Mo's algorithm with updates */ 2 | 3 | /* 4 | https://codeforces.com/blog/entry/72690 5 | */ 6 | 7 | struct Query { 8 | static const int block_size = pow(N, 0.66) + 1; // O(N ^ 5/3) when N ≈ Q 9 | 10 | int l, r, t, idx; tuple cmp; 11 | Query(int l, int r, int t, int idx) 12 | : l(l), r(r), t(t), idx(idx), cmp( 13 | l / block_size, 14 | (l / block_size & 1? r / block_size : -r / block_size), 15 | (r / block_size & 1? t : -t) 16 | ) {} 17 | 18 | bool operator<(const Query& o) const { 19 | return cmp < o.cmp; 20 | } 21 | }; 22 | 23 | vector queries; 24 | vector> updates; // 25 | queries.reserve(Q) updates.reserve(Q); 26 | 27 | while(Q--) { 28 | int type; cin >> type; 29 | if(type == 1) { 30 | int l, r; cin >> l >> r; 31 | queries.emplace_back(--l, r, updates.size(), queries.size()); 32 | } else { 33 | int pos, val; cin >> pos >> val; --pos; 34 | updates.emplace_back(pos, a[pos], val); a[pos] = val; 35 | } 36 | } sort(queries.begin(), queries.end()); 37 | 38 | // [l, r) 39 | int l = 0, r = 0, t = updates.size(); 40 | int64_t cur = 0; 41 | 42 | auto update = [&](int val, int delta) { 43 | 44 | }; 45 | 46 | auto changever = [&](int t, int dir, int l, int r) { 47 | auto [pos, old, nw] = updates[t]; 48 | if(dir == -1) swap(old, nw); 49 | if(l <= pos and pos < r) 50 | update(old, -1), update(nw, +1); 51 | a[pos] = nw; 52 | }; 53 | 54 | vector ans(queries.size()); 55 | for(auto& q: queries) { 56 | while(l > q.l) 57 | update(a[--l], +1); 58 | while(r < q.r) 59 | update(a[r++], +1); 60 | while(l < q.l) 61 | update(a[l++], -1); 62 | while(r > q.r) 63 | update(a[--r], -1); 64 | while(t < q.t) 65 | changever(t++, +1, l, r); 66 | while(t > q.t) 67 | changever(--t, -1, l, r); 68 | ans[q.idx] = cur; 69 | } -------------------------------------------------------------------------------- /末 Snippets/Mo's Algorithm/Mo's algorithm.cpp: -------------------------------------------------------------------------------- 1 | /* Mo's algorithm */ 2 | 3 | /* 4 | Blog: 5 | https://codeforces.com/blog/entry/88494 6 | https://codeforces.com/blog/entry/81716 7 | */ 8 | 9 | vector queries; 10 | queries.reserve(Q); 11 | for(i = 0; i < Q; i++) { 12 | int l, r; cin >> l >> r; 13 | queries.emplace_back(--l, r, i); 14 | } 15 | 16 | sort(queries.begin(), queries.end()); 17 | 18 | // [l, r) 19 | int l = 0, r = 0; 20 | int64_t cur = 0; 21 | 22 | auto update = [&](int val, int delta) { 23 | 24 | }; 25 | 26 | vector ans(Q); 27 | for(auto& q: queries) { 28 | while(l > q.l) 29 | update(a[--l], +1); 30 | while(r < q.r) 31 | update(a[r++], +1); 32 | while(l < q.l) 33 | update(a[l++], -1); 34 | while(r > q.r) 35 | update(a[--r], -1); 36 | ans[q.idx] = cur; 37 | } -------------------------------------------------------------------------------- /末 Snippets/Mo's Algorithm/Query struct (Canonical).cpp: -------------------------------------------------------------------------------- 1 | /* Query struct - canonical */ 2 | 3 | struct Query { 4 | static const int block_size = 1.6 * sqrt(N) + 1; 5 | // static const int block_size = N / sqrt(Q) + 1; 6 | 7 | int l, r, idx, b; 8 | Query(int l, int r, int idx) 9 | : l(l), r(r), idx(idx), b(l / block_size) {} 10 | 11 | bool operator<(const Query& o) const { 12 | return b ^ o.b? l < o.l : b & 1? r > o.r : r < o.r; 13 | } 14 | }; -------------------------------------------------------------------------------- /末 Snippets/Mo's Algorithm/Query struct (Hilbert ordering).cpp: -------------------------------------------------------------------------------- 1 | /* Query struct - Hilbert ordering */ 2 | 3 | /* 4 | https://codeforces.com/blog/entry/61203 5 | */ 6 | 7 | int64_t hilbertorder(int x, int y) { 8 | static constexpr int LG = 31 - __builtin_clz(N) + !!(N & N-1); 9 | static constexpr int maxn = 1 << LG; 10 | 11 | int64_t d = 0; 12 | for(int s = 1 << (LG - 1); s; s >>= 1) { 13 | bool rx = x & s, ry = y & s; 14 | d = d << 2 | rx * 3 ^ static_cast(ry); 15 | if(!ry) { 16 | if(rx) x = maxn - x, y = maxn - y; 17 | swap(x, y); 18 | } 19 | } return d; 20 | } 21 | 22 | struct Query { 23 | int l, r, idx; 24 | int64_t ord; 25 | 26 | Query(int l, int r, int idx) 27 | : l(l), r(r), idx(idx), ord(hilbertorder(l + 1, r)) {} 28 | 29 | bool operator<(const Query& o) const { 30 | return ord < o.ord; 31 | } 32 | }; -------------------------------------------------------------------------------- /末 Snippets/PBDS.cpp: -------------------------------------------------------------------------------- 1 | /* Policy Based Data Structures - ordered_set */ 2 | 3 | /* 4 | https://codeforces.com/blog/entry/11080 5 | 6 | Problems: 7 | https://codeforces.com/contest/1324/problem/D 8 | https://codeforces.com/contest/255/problem/C 9 | https://cses.fi/problemset/task/2168 10 | https://cses.fi/problemset/task/2169 11 | https://cses.fi/problemset/task/2163 12 | https://codeforces.com/contest/1262/problem/D2 13 | https://codeforces.com/contest/1311/problem/F 14 | https://codeforces.com/contest/1191/problem/F 15 | https://codeforces.com/contest/1401/problem/E 16 | https://codeforces.com/contest/1005/problem/E2 17 | */ 18 | 19 | #include 20 | #include 21 | using namespace __gnu_pbds; 22 | template> 23 | using ordered_set = tree; 24 | #define ook order_of_key // count of elements strictly smaller than k 25 | #define fbo find_by_order // iterator to kth element starting from 0 26 | 27 | ordered_set os; 28 | ordered_set> os; 29 | ordered_set o_map; 30 | ordered_set> os_greater; -------------------------------------------------------------------------------- /末 Snippets/Pollard rho.cpp: -------------------------------------------------------------------------------- 1 | /* Pollard Rho integer factorization */ 2 | 3 | /* 4 | Blog: https://www.cs.colorado.edu/~srirams/courses/csci2824-spr14/pollardsRho.html 5 | Alt implementation: http://morris821028.github.io/2015/07/11/uva-11476/ 6 | */ 7 | 8 | uint64_t modmul(uint64_t a, uint64_t b, uint64_t M) { 9 | int64_t ret = a * b - M * uint64_t(1.L / M * a * b); 10 | return ret + M * (ret < 0) - M * (ret >= (int64_t)M); 11 | } 12 | 13 | uint64_t modpow(uint64_t b, uint64_t e, uint64_t mod) { 14 | uint64_t ans = 1; 15 | for(; e; b = modmul(b, b, mod), e /= 2) 16 | if(e & 1) ans = modmul(ans, b, mod); 17 | return ans; 18 | } 19 | 20 | bool isPrime(uint64_t n) { 21 | if(n < 2 || n % 6 % 4 != 1) return (n | 1) == 3; 22 | uint64_t A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022}, 23 | s = __builtin_ctzll(n-1), d = n >> s; 24 | for(uint64_t a: A) { 25 | uint64_t p = modpow(a%n, d, n), i = s; 26 | while(p != 1 && p != n - 1 && a % n && i--) 27 | p = modmul(p, p, n); 28 | if(p != n-1 && i != s) return 0; 29 | } return 1; 30 | } 31 | 32 | uint64_t pollard(uint64_t n) { 33 | auto f = [n](uint64_t x) { return modmul(x, x, n) + 1; }; 34 | uint64_t x = 0, y = 0, t = 0, prd = 2, i = 1, q; 35 | while(t++ % 40 || __gcd(prd, n) == 1) { 36 | if(x == y) x = ++i, y = f(x); 37 | if((q = modmul(prd, max(x,y) - min(x,y), n))) prd = q; 38 | x = f(x), y = f(f(y)); 39 | } return __gcd(prd, n); 40 | } 41 | 42 | vector factor(uint64_t n) { 43 | if(n == 1) return {}; 44 | if(isPrime(n)) return {n}; 45 | uint64_t x = pollard(n); 46 | auto l = factor(x), r = factor(n / x); 47 | l.insert(l.end(), r.begin(), r.end()); sort(l.begin(), l.end()); 48 | return l; 49 | } 50 | // int64_t x = 6969696923423424; 51 | // auto factors = factor(x); 52 | // ~ {2, 2, 2, 2, 2, 2, 3, 37, 281, 2029, 1720769} -------------------------------------------------------------------------------- /末 Snippets/Remove duplicates.cpp: -------------------------------------------------------------------------------- 1 | /* Sort vector and remove duplicates */ 2 | 3 | vector vec{1, 1, 1, 2, 3, 3}; 4 | sort(vec.begin(), vec.end()); 5 | vec.erase(unique(vec.begin(), vec.end()), vec.end()); 6 | -------------------------------------------------------------------------------- /末 Snippets/Run with larger stack size.cpp: -------------------------------------------------------------------------------- 1 | /* Run with larger stack size */ 2 | 3 | /* 4 | > directly from code 5 | https://codeforces.com/blog/entry/94726?#comment-839042 6 | */ 7 | 8 | void main_() { 9 | int i, n; 10 | cin >> n; 11 | 12 | } 13 | 14 | static void run_with_stack_size(void (*func)(void), size_t stsize) { 15 | char *stack, *send; 16 | stack = (char *)malloc(stsize); 17 | send = stack + stsize - 16; 18 | send = (char *)((uintptr_t)send / 16 * 16); 19 | asm volatile( 20 | "mov %%rsp, (%0)\n" 21 | "mov %0, %%rsp\n" 22 | : 23 | : "r"(send)); 24 | func(); 25 | asm volatile("mov (%0), %%rsp\n" : : "r"(send)); 26 | free(stack); 27 | } 28 | 29 | int main() { 30 | run_with_stack_size(main_, 1024 * 1024 * 1024); // 1 GB 31 | return 0; 32 | } 33 | 34 | /* 35 | > via command line 36 | 37 | Windows: 38 | g++ -Wl,-stack=1073741824 -std=c++17 file.cpp -o file // 1 GB 39 | 40 | Linux: 41 | ulimit -s unlimited && g++ -std=c++17 file.cpp -o file // replace 1048576 with for 1 GB 42 | */ 43 | 44 | -------------------------------------------------------------------------------- /末 Snippets/SCC (Kosaraju's algo).cpp: -------------------------------------------------------------------------------- 1 | /* Strongly Connected Components - Kosaraju's algorithm */ 2 | 3 | /* 4 | https://www.youtube.com/watch?v=z9oOadBgO9I&ab_channel=AlgorithmsLive 5 | https://cp-algorithms.com/graph/strongly-connected-components.html 6 | */ 7 | 8 | int sccount = 0; 9 | vector> g(n), rg(n); 10 | vector comp(n, -1), order; 11 | 12 | auto dfs = Y([&](auto dfs, int v, int k, const auto& gr) -> void { 13 | comp[v] = k; 14 | for(auto& x: gr[v]) 15 | if(comp[x] == -1) dfs(x, k, gr); 16 | if(k == -2) order.push_back(v); 17 | }); 18 | 19 | order.reserve(n); 20 | for(i = 0; i < n; i++) 21 | if(comp[i] == -1) dfs(i, -2, g); 22 | 23 | comp.assign(n, -1); 24 | while(!order.empty()) { 25 | dfs(order.back(), sccount++, rg); 26 | while(!order.empty() and ~comp[order.back()]) 27 | order.pop_back(); 28 | } -------------------------------------------------------------------------------- /末 Snippets/SCC (Tarjan's algo).cpp: -------------------------------------------------------------------------------- 1 | /* Strongly Connected Components - Tarjan's algorithm */ 2 | 3 | /* 4 | Algorithms Live: 5 | https://www.youtube.com/watch?v=z9oOadBgO9I&ab_channel=AlgorithmsLive 6 | */ 7 | 8 | int sccount = 0; 9 | vector id(n, -1), low(n), onstack(n), comp(n); 10 | stack st; 11 | 12 | // Tarjan's SCC, produces reverse topsort by comp id 13 | auto dfs = Y([&, cur_id = 0](auto self, int v) mutable -> void { 14 | id[v] = low[v] = cur_id++; 15 | onstack[v] = true; st.push(v); 16 | for(auto& x: g[v]) { 17 | if(id[x] == -1) self(x), low[v] = min(low[v], low[x]); 18 | else if(onstack[x]) low[v] = min(low[v], low[x]); 19 | } if(low[v] == id[v]) { 20 | while(st.top() != v) { 21 | comp[st.top()] = sccount; 22 | onstack[st.top()] = false; st.pop(); 23 | } comp[v] = sccount++; onstack[v] = false; st.pop(); 24 | } 25 | }); 26 | 27 | for(i = 0; i < n; i++) 28 | if(id[i] == -1) dfs(i); -------------------------------------------------------------------------------- /末 Snippets/Segment trees/Iterative + Point updates (+ link to range updates).cpp: -------------------------------------------------------------------------------- 1 | /* Iterative segment tree with point updates */ 2 | 3 | int main() { 4 | int i, n, Q; 5 | cin >> n >> Q; 6 | 7 | vector seg(n << 1); 8 | for(i = 0; i < n; i++) 9 | cin >> seg[i + n]; 10 | 11 | // build 12 | for(i = n-1; i; i--) 13 | seg[i] = seg[i << 1] + seg[i << 1 | 1]; 14 | 15 | // query [l, r) 16 | auto query = [n, &seg](int l, int r) { 17 | int64_t res = 0; 18 | for(l += n, r += n; l < r; l >>= 1, r >>= 1) { 19 | if(l&1) res += seg[l++]; 20 | if(r&1) res += seg[--r]; 21 | } return res; 22 | }; 23 | 24 | // update pos, val 25 | auto update = [n, &seg](int pos, int val) { 26 | for(seg[pos += n] = val; pos >>= 1; ) 27 | seg[pos] = seg[pos << 1] + seg[pos << 1 | 1]; 28 | }; 29 | 30 | while(Q--) { 31 | int o; cin >> o; 32 | if(o == 1) { 33 | int pos, val; cin >> pos >> val; 34 | update(--pos, val); 35 | } else { 36 | int l, r; cin >> l >> r; 37 | cout << query(--l, r) << '\n'; 38 | } 39 | } 40 | } 41 | 42 | /* 43 | Blog: https://codeforces.com/blog/entry/18051 44 | Hello world: https://cses.fi/problemset/task/1648/ 45 | More problems: https://codeforces.com/edu/course/2/lesson/4 46 | Lazy prop variant: https://codeforces.com/contest/343/submission/24869698 47 | https://codeforces.com/contest/1550/submission/122582660 48 | */ -------------------------------------------------------------------------------- /末 Snippets/Sieve of Eratosthenes.cpp: -------------------------------------------------------------------------------- 1 | /* Sieve of Eratosthenes */ 2 | 3 | /* 4 | https://github.com/the-hyp0cr1t3/CC/blob/master/Beginner%20Topics/%5BS2%5D%20Primal%20proficiency/%5BEP%202%5D%20Primality%2C%20Factorization%20and%20Sieve.md 5 | */ 6 | 7 | const int N = 1e7; 8 | // spf = smallest prime factor 9 | array spf; iota(spf.begin(), spf.end(), 0); 10 | vector primes{2}; primes.reserve(N); 11 | for(int z = 4; z < N; z += 2) spf[z] = 2; 12 | for(int z = 3; z*z < N; z += 2) if(spf[z] == z) { 13 | for(int y = z*z; y < N; y += z*2) 14 | if(spf[y] == y) spf[y] = z; 15 | } 16 | for(int z = 3; z < N; z += 2) 17 | if(spf[z] == z) primes.push_back(z); 18 | -------------------------------------------------------------------------------- /末 Snippets/Sparse Table.cpp: -------------------------------------------------------------------------------- 1 | /* Sparse table for offline range queries */ 2 | 3 | /* 4 | https://codeforces.com/blog/entry/93846 5 | */ 6 | 7 | template 8 | struct Sparse { 9 | int N, K; Cmp cmp; 10 | vector> table; vector> idx; 11 | int lg(int x) const { return 31 - __builtin_clz(x); } 12 | template 13 | explicit Sparse(Iter beg, Iter end, Func&& f) 14 | : N(end-beg), K(this->lg(N)), cmp(forward(f)), 15 | table(K+1, vector(N)), idx(K+1, vector(N)) { 16 | for(int i = 0; i < N; i++) { 17 | table[0][i] = *(beg+i); 18 | idx[0][i] = i; 19 | } 20 | for(int k = 1; k <= K; k++) { 21 | for(int i = 0; i+(1< 41 | Sparse(T, T, Cmp) -> Sparse::value_type, Cmp>; // template deduction guide (C++17) 42 | 43 | /* 44 | int32_t main() { 45 | int arr[] = {1, 2, 3, 5}; 46 | vector a{1, 2, 3, 5}; 47 | Sparse st1(a.begin(), a.end(), std::less{}); 48 | Sparse st2(a.begin(), a.end(), [](int x, int y){ return x < y; }); 49 | 50 | Sparse st3(arr, arr+n, std::less{}); 51 | Sparse st4(arr, arr+n, [](int x, int y){ return x < y; }); 52 | 53 | // For C++14 or before, do something like 54 | auto cmp = [](int x, int y){ return x < y; }; 55 | Sparse st(a.begin(), a.end(), cmp); 56 | } 57 | */ 58 | -------------------------------------------------------------------------------- /末 Snippets/Spread queue (using two stacks).cpp: -------------------------------------------------------------------------------- 1 | /* Spread queue (using two stacks) */ 2 | 3 | 4 | /* 5 | Calculate and maintain associative functions over a segment (pair with 2-pointer) in O(n) 6 | Eg: Find the number of segments of an array with gcd = 1 or max - min <= k 7 | 8 | Blog: 9 | https://codeforces.com/edu/course/2/lesson/9/2 10 | 11 | Gcd: 12 | https://codeforces.com/edu/course/2/lesson/9/2/practice/contest/307093/problem/G 13 | http://p.ip.fi/ow-L 14 | 15 | Min-max: 16 | https://codeforces.com/edu/course/2/lesson/9/2/practice/contest/307093/problem/F 17 | http://p.ip.fi/GWT_ 18 | */ 19 | 20 | // T = val, e is the identity element (e ⊕ a = a ⊕ e = a) 21 | // T f(T, T) 22 | template 23 | class SpreadQueue { 24 | int size; T in; F f; 25 | stack out, val_in, val_out; 26 | 27 | public: 28 | template 29 | SpreadQueue(G&& g): f(forward(g)), size(0), in(e) { out.push(e); } 30 | 31 | void push(T v) { 32 | val_in.push(v); in = f(in, v); size++; 33 | } 34 | 35 | void pop() { 36 | if(val_out.empty()) { 37 | while(!val_in.empty()) { 38 | val_out.push(val_in.top()); val_in.pop(); 39 | out.push(f(val_out.top(), out.top())); 40 | } in = e; 41 | } out.pop(); val_out.pop(); assert(size--); 42 | } 43 | 44 | T best() const { 45 | return empty()? e : f(in, out.top()); 46 | } 47 | 48 | bool empty() const { return !size; } 49 | }; 50 | 51 | // make 52 | template 53 | auto make_SpreadQueue(F&& f) { 54 | return SpreadQueue (forward(f)); 55 | } 56 | 57 | int main() { 58 | 59 | // gcd spread eg 60 | auto q = make_SpreadQueue([](auto x, auto y) { return gcd(x, y); }); 61 | 62 | // min and max spread 63 | auto mnq = make_SpreadQueue( 64 | [](auto x, auto y) { return min(x, y); }); 65 | auto mxq = make_SpreadQueue( 66 | [](auto x, auto y) { return max(x, y); }); 67 | 68 | } -------------------------------------------------------------------------------- /末 Snippets/Topsort.cpp: -------------------------------------------------------------------------------- 1 | /* Topological sort */ 2 | 3 | /* 4 | https://cp-algorithms.com/graph/topological-sort.html 5 | */ 6 | 7 | int indeg[N]; 8 | vector g[N]; 9 | 10 | for(i = 0; i < m; i++) { 11 | int u, v; cin >> u >> v; u--, v--; 12 | g[u].push_back(v); 13 | indeg[v]++; 14 | } 15 | 16 | auto topsort = [&]() { 17 | queue q; vector order; 18 | order.reserve(n); 19 | for(i = 0; i < n; i++) 20 | if(!indeg[i]) q.push(i); 21 | while(!q.empty()) { 22 | auto v = q.front(); q.pop(); 23 | order.push_back(v); 24 | for(auto& x: g[v]) 25 | if(!--indeg[x]) q.push(x); 26 | } return order.size() == n; // cycle? false : true 27 | }; -------------------------------------------------------------------------------- /末 Snippets/Y combinator.cpp: -------------------------------------------------------------------------------- 1 | /* Y combinator - facilitate recursion in lambdas */ 2 | 3 | /* 4 | Inspired by [ecnerwala](https://codeforces.com/profile/ecnerwala) 5 | Read more from [here](https://mvanier.livejournal.com/2897.html) 6 | */ 7 | 8 | using namespace std; 9 | template class Y { 10 | T f_; 11 | public: 12 | template explicit Y(U&& f): f_(forward(f)) {} 13 | template decltype(auto) operator()(Args&&... args) { 14 | return f_(ref(*this), forward(args)...); 15 | } 16 | }; template Y(T) -> Y; // template deduction guide (C++17) 17 | 18 | //For C++14 and before, refer to [submission](https://codeforces.com/contest/1466/submission/102864010) 19 | 20 | auto factorial = Y([&](auto self, int n) -> int { 21 | return n == 0? 1 : n * self(n-1); 22 | }); 23 | 24 | std::cout << factorial(5); 25 | -------------------------------------------------------------------------------- /末 Snippets/Z algo.cpp: -------------------------------------------------------------------------------- 1 | /* Z algorithm */ 2 | 3 | /* 4 | https://cp-algorithms.com/string/z-function.html 5 | See also: KMP 6 | */ 7 | 8 | // z[i] is the longest proper prefix 9 | // that is starts at position i 10 | // aaa.aaaba 11 | // 021 32101 12 | auto generate_z = [](const string& s) { 13 | // s = (pattern + '#' + text) 14 | int n = s.size(); 15 | vector z(n); 16 | for(int k = 1, l = 0, r = 0; k < n; ++k) { 17 | if(k <= r) 18 | z[k] = min(r - k + 1, z[k - l]); 19 | while(k + z[k] < n and s[z[k]] == s[k + z[k]]) 20 | z[k]++; 21 | if(k + z[k] - 1 > r) 22 | l = k, r = k + z[k] - 1; 23 | } 24 | return z; 25 | }; 26 | -------------------------------------------------------------------------------- /末 Snippets/nCr.cpp: -------------------------------------------------------------------------------- 1 | /* nCr | Combination(n, r) | N choose R ~ n things taken r at a time without repetition */ 2 | 3 | /* 4 | - Mod operations are implicitly handled by ModInt struct mint 5 | - May also be used without by performing required mod ops where necessary 6 | */ 7 | 8 | int maxN = 1e6; 9 | 10 | static vector fact{1, 1}, factinv{1, 1}, inv{0, 1}; 11 | 12 | fact.reserve(maxN); factinv.reserve(maxN); inv.reserve(maxN); 13 | for(int z = fact.size(); z < maxN; z++) { 14 | // [Modular inverse](https://cp-algorithms.com/algebra/module-inverse.html#mod-inv-all-num) 15 | inv.push_back(inv[MOD % z] * (MOD - MOD / z)); 16 | fact.push_back(z * fact[z-1]); 17 | factinv.push_back(inv[z] * factinv[z-1]); 18 | } 19 | 20 | auto nCr = [&](int n, int r) { 21 | return r < 0 or r > n? 0 : fact[n] * factinv[r] * factinv[n-r]; 22 | }; 23 | --------------------------------------------------------------------------------