Learn the low-friction patterns first: monotone search, prefix preprocessing, window scans, and basic traversal.
Binary Search, Prefix Sums and Difference Arrays, Two Pointers and Sliding Window, BFS and DFS
Long-form notes on the algorithms, data structures, and contest patterns I want to keep in a form that is still useful months later.
The landing note explains the scope; the taxonomy section keeps the bigger map visible.
These notes are the part of the competitive programming archive that is not tied to one contest year. The goal is simple: keep the ideas that I actually want to reuse in a form that is still readable after the adrenaline of the original contest is gone.
I care about three things here:
the structural reason an algorithm or data structure works,
the implementation shape I would still trust in contest code,
the failure modes that usually cause wrong answers or wasted time.
Each topic keeps note.tex as the written source of truth and code.cpp as the implementation source of truth. The site renders the TeX into HTML and shows the C++ file separately, so the prose can stay focused while the code remains directly copyable.
The finished notes are meant to be public-facing study material, not private scraps. That means the emphasis is on explanations, invariants, use cases, and pitfalls instead of dumping templates with no context.
If I were revising this section from scratch, I would split it into a few routes instead of pretending there is one universal order:
core first: binary search, prefix sums, sliding window, coordinate compression, Fenwick tree, BFS / DFS,
graph path: topological sort, Dijkstra, MST, SCC, Euler tour, LCA, tree decompositions,
DP optimization path: knapsack, tree DP, monotone queue, divide-and-conquer DP, Knuth, convex hull trick, rerooting,
advanced data structures: segment tree, sparse table, ordered set, Li Chao tree, persistent segment tree, rollback DSU,
number theory path: extended Euclid, modular arithmetic, CRT, sieve, Mobius, Miller-Rabin, discrete log.
That is still not the only valid order, but it is closer to how I actually revise: pick a branch, stay inside it long enough for the invariants to become familiar, then switch.
A finished note should answer the questions I usually care about when revising:
What kind of contest situation makes this the right tool?
What invariant is doing the real work?
Which implementation shape is the least fragile under time pressure?
Which edge cases usually break the first version?
What does a worked contest-style example actually look like?
Some topics are still only planned. They are listed openly as planned instead of pretending that a shallow page is enough.
The explanations are rewritten in my own words, but the topic map and many implementation choices were informed by:
These notes form the shortest useful route into the section before the more structural topics take over.
A decision-to-answer pattern for monotone predicates, answer-space search, and continuous approximation.
basicTurn repeated range work into constant-time queries or constant-time lazy marks by changing what the array stores.
basicExploit one-way pointer movement to turn many quadratic scans into linear passes over arrays and strings.
basicThe fundamental graph traversals for reachability, layering, component discovery, and tree exploration.
basicA compact range-query structure for point updates, prefix sums, and frequency-based order statistics.
basicPrefix-function based linear-time string matching with no backtracking in the text.
The section is intentionally uneven: the counts below show where the dense reusable notes already exist and where the next pass still has room to grow.
Each category page now shows finished notes, planned topics, recommended order, and level distribution, so it is easier to decide whether to revise breadth-first or go deep on one branch.
These are the habits and small techniques that decide whether a problem is a quick implementation or an unnecessary detour.
Open Fundamentals 02 Data StructuresThis branch focuses on structures that trade memory, invariants, or amortization for faster updates and queries.
Open Data Structures 03 Graph AlgorithmsWhen a problem hides an interaction graph, these notes aim to make the graph structure explicit instead of magical.
Open Graph Algorithms 04 Dynamic ProgrammingThe focus here is less on memorizing formulas and more on seeing what information must survive from one decision to the next.
Open Dynamic Programming 05 Number TheoryThese notes emphasize the parts of number theory that become algorithms rather than standalone proofs.
Open Number Theory 06 String AlgorithmsString problems are often bookkeeping problems in disguise. The goal is to keep the invariant small enough to update in linear time.
Open String Algorithms 07 GeometryThe intended emphasis is contest geometry that survives integer arithmetic, not coordinate-free elegance for its own sake.
Open Geometry 08 Flows and MatchingThis branch collects problems where the cleanest solution is to phrase the whole task as conserved flow or structural matching.
Open Flows and Matching 09 Advanced TricksThese topics are the part of competitive programming that is hardest to compress into one sentence but easiest to recognize after enough practice.
Open Advanced TricksThe notes are cross-linked by topic, but this order keeps the prerequisites and implementation burden under control.
Learn the low-friction patterns first: monotone search, prefix preprocessing, window scans, and basic traversal.
Binary Search, Prefix Sums and Difference Arrays, Two Pointers and Sliding Window, BFS and DFS
Add the first reusable data structures and string baselines once the array and graph patterns feel routine.
Fenwick Tree, Segment Tree, Disjoint Set Union, KMP, Z-Function, Topological Sort
This is where tree queries, heavier DP, and flow or number-theory machinery start paying off.
Lazy Segment Tree, Sparse Table, Knapsack, Tree DP, Dijkstra, Lowest Common Ancestor, Dinic, NTT
Keep the amortized and pointer-heavy machinery for after the more standard contest baselines are stable.
Heavy-Light Decomposition, Convex Hull Trick, Splay Tree, Link-Cut Tree, Min-Cost Max-Flow
These routes are meant to reduce thrashing. Each one keeps related ideas close enough that implementation habits carry over from note to note.
Use this if the goal is broad contest fluency before specializing. It stays close to the patterns that appear in array, graph, and prefix-processing problems.
Binary Search, Binary Search on Answer, Prefix Sums and Difference Arrays, Two Pointers and Sliding Window, Coordinate Compression, Fenwick Tree, BFS and DFS
Follow this route if tree structure, connectivity, and path queries are the current bottleneck.
BFS and DFS, Topological Sort, Dijkstra, Minimum Spanning Tree, Strongly Connected Components, Euler Tour Technique, Lowest Common Ancestor (Binary Lifting), Centroid Decomposition
This path is for when the recurrence is already visible and the remaining problem is state reduction or transition acceleration.
Knapsack, Tree DP, Monotone Queue Optimization, Divide and Conquer DP Optimization, Knuth Optimization, Convex Hull Trick, Rerooting DP, Aliens Trick / Lagrangian Relaxation
Take this when the implementation burden is acceptable and the main task is choosing the right structural invariant.
Fenwick Tree, Segment Tree, Sparse Table, Ordered Set (Policy-Based Data Structures), Li Chao Tree, Persistent Segment Tree, DSU Rollback, Wavelet Tree
This route starts from the arithmetic tools that appear everywhere, then moves into structure-heavy topics such as CRT, multiplicative functions, and primality machinery.
GCD and Extended Euclid, Modular Arithmetic, Modular Inverse, Sieve of Eratosthenes, Prime Factorization, Chinese Remainder Theorem, Mobius Function, Miller-Rabin and Pollard Rho, Primitive Roots and Discrete Logarithm
The first pass focuses on notes I expect to reuse often in contest prep, implementation review, and post-contest study.
A decision-to-answer pattern for monotone predicates, answer-space search, and continuous approximation.
Optimize a unimodal function on a discrete or continuous domain by keeping the side that still contains the optimum.
Turn repeated range work into constant-time queries or constant-time lazy marks by changing what the array stores.
Exploit one-way pointer movement to turn many quadratic scans into linear passes over arrays and strings.
Turn interval and query problems into a left-to-right sweep over sorted add, remove, and inspect events.
Compact subset state, fast bit operations, and the enumeration patterns that power many small-state solutions.
A proof pattern for showing that one locally optimal choice can be forced into some global optimum without making the solution worse.
Replace large or sparse values by their rank order so array-based structures become practical again.
Split an exponential search into two smaller exponential searches and join the halves with sorting or hashing.
A compact range-query structure for point updates, prefix sums, and frequency-based order statistics.
Maintain candidates in sorted order of value so next-greater and sliding-window extrema can be updated in linear time.
Extend the Fenwick tree idea to point updates and rectangle sums on a grid.
The general-purpose interval tree for logarithmic range queries and updates when Fenwick is too small.
The standard extension of a segment tree when range updates must stay logarithmic too.
A static range-query structure that turns immutable RMQ-style queries into O(1) lookups.
Union-find for dynamic connectivity and component bookkeeping when edges only merge components.
A randomized BST built from split and merge, with order statistics and clean structural recursion.
A self-adjusting BST that pays for flexibility with amortized analysis instead of explicit balance invariants.
A dynamic-forest structure built on splay trees for link, cut, reroot, and path-query operations.
An indexed balanced tree for order statistics when std::set is not enough and a full custom BST is overkill.
A segment-tree-style structure for maintaining a dynamic lower envelope of lines under point queries.
Path-copy only the changed nodes so every update creates a new version without destroying the old one.
A union-find variant that can undo merges, which is the missing piece behind offline dynamic connectivity.
Build a tree whose inorder traversal is the array order and whose heap property exposes range minima or maxima.
Recursively partition values so k-th order statistics and frequency queries on subarrays can be answered quickly.
The fundamental graph traversals for reachability, layering, component discovery, and tree exploration.
Single-source shortest paths in non-negative weighted graphs with a min-heap and lazy deletions.
Order a DAG so every directed edge points forward, then reuse that order for dependency processing and DAG DP.
Connect a weighted graph as cheaply as possible, usually with Kruskal and DSU as the contest default.
Flatten a rooted tree into entry and exit times so subtree queries become interval queries on an array.
Lift nodes by powers of two so LCA and ancestor queries become logarithmic after one tree preprocessing pass.
Compress a directed graph into its mutually reachable blocks, then reason on the resulting DAG instead of the original cycles.
Use DFS lowlink values to find edges or vertices whose removal disconnects an undirected graph.
Reduce two-literal clauses to an implication graph, then solve satisfiability with SCC decomposition.
Compress a query's marked nodes and the LCAs between them into a much smaller tree that preserves the relevant paths.
Recursively split a tree by balanced centroids so global path problems can be reduced to logarithmically many local views.
Reduce tree path queries to a logarithmic number of segment queries by carving the tree into heavy chains.
The standard capacity-based DP pattern, with the loop directions and state choices that distinguish 0/1 from unbounded use.
Dynamic programming over subsets when the state is a small visited set, partition, or compatibility frontier.
A position-by-position DP over the decimal expansion of an upper bound, with tight and leading-zero states.
Exploit the parent-child structure of trees so each state only has to summarize one rooted subtree at a time.
Speed up DP transitions over a sliding range by keeping only the best candidates in a deque.
Speed up row-by-row transition minimization when the optimal split point moves monotonically.
Speed up interval DP from O(n^3) to O(n^2) when the optimal split points move monotonically.
A deque-based lower hull for DP recurrences with monotone slopes and monotone queries.
Transform subset-based values so every mask can aggregate information from all of its submasks or supermasks efficiently.
Compute a tree answer for every possible root by combining one downward DP pass with one upward transfer pass.
Replace a hard limit on the number of chosen groups with a penalty and binary search that penalty.
The basic divisibility toolkit for reducing fractions, solving linear equations, and building modular arithmetic routines.
Keep arithmetic safe under a modulus by tracking the algebraic rules that still survive after reduction.
Undo multiplication modulo m when the gcd condition allows it, and choose the right inverse routine for the modulus.
Precompute primality and smallest prime factors once, then answer many prime-related queries cheaply.
Combine modular constraints into one congruence when the residue classes are compatible.
Break numbers into prime powers and choose the right factorization strategy for the size and query pattern.
Count how many integers up to n are coprime to n, and use the factorization formula to turn that count into code.
Use the Mobius function and inversion to separate exact divisibility structure from overcounted multiples.
Polynomial convolution modulo 998244353 using roots of unity and iterative butterfly layers.
Work inside cyclic multiplicative groups by finding generators and solving exponent equations with baby-step giant-step.
The standard 64-bit primality and factorization toolkit once trial division stops being realistic.
Recover or evaluate a low-degree polynomial from sample points, usually with modular Lagrange interpolation.
Prefix-function based linear-time string matching with no backtracking in the text.
Measure how much each suffix matches the full string, then reuse that linear-time structure for pattern matching and periodicity.
A fast probabilistic fingerprint for substring comparison, string sets, and prefix-based matching tricks.
Store strings by prefix so inserts, prefix checks, and dictionary transitions depend on length rather than set size.
Sort all suffixes once, then reuse the order and LCP information for many substring and lexicographic queries.
A linear-time substring automaton that is especially good at online extension, distinct-substring counts, and occurrence queries.
Compute longest odd and even palindromic radii around every center in linear time.
A trie with failure links that searches many patterns in one text in a single pass.
The core integer-geometry predicate behind turns, area tests, segment intersection, and hull construction.
Build the outer envelope of a point set with monotone chain and use it as the basis for many geometry reductions.
Reliable line and segment intersection tests built on orientation, with exact predicates and careful boundary handling.
Classify a point as outside, on the boundary, or inside a polygon with a contest-ready ray-crossing routine.
Walk two pointers around a convex polygon to enumerate antipodal structure without restarting from scratch.
Find the nearest pair of points in O(n log n) with divide and conquer and a y-sorted strip check.
A layered-network max-flow algorithm that is fast enough for most contest flow models and reusable in many reductions.
Match the two sides of a bipartite graph efficiently, and recognize when the problem is assignment rather than general flow.
Find a maximum bipartite matching faster than repeated DFS by growing many shortest augmenting paths in one phase.
Send flow while optimizing total cost, which turns assignment and constrained transport models into graph problems.
Turn optimization into repeated feasibility checks by designing a monotone predicate over the answer space.
Answer many monotone offline queries at once by testing them in batches at shared midpoints.
Offline range-query ordering that trades sorting plus add/remove operations for fast answers on static arrays.
Reorder queries so that one sweep or one monotone data-structure state can answer them more cheaply than online processing.
Amortize repeated subtree merges by always moving the smaller container into the larger one.
Split the array into blocks so point updates and range queries become simple block-level work instead of full rescans.
Use machine-word parallelism to update or compare dozens of boolean states with one operation.
These notes are the ones most likely to repay a slower read: they unlock bigger structures, stronger reductions, or heavier implementation patterns.
A self-adjusting BST that pays for flexibility with amortized analysis instead of explicit balance invariants.
A dynamic-forest structure built on splay trees for link, cut, reroot, and path-query operations.
Reduce tree path queries to a logarithmic number of segment queries by carving the tree into heavy chains.
A deque-based lower hull for DP recurrences with monotone slopes and monotone queries.
Polynomial convolution modulo 998244353 using roots of unity and iterative butterfly layers.
This is the stable topic map for the section: some entries already have full notes, others are intentionally marked as planned.
Complexity analysis
Sorting
Binary search
Ternary search
Two pointers
Prefix sums
Difference arrays
Coordinate compression
Sorting + events
Greedy exchange argument
Bitmasks
Meet-in-the-middle
Fenwick tree
2D Fenwick tree
Segment tree
Lazy segment tree
Sparse table
Disjoint set union
Monotonic stack / queue
Ordered set
Treap
Splay tree
Cartesian tree
Persistent segment tree
Li Chao tree
Link-cut tree
Trie
Wavelet tree
DFS / BFS
Topological sort
Dijkstra
Bellman-Ford
Floyd-Warshall
LCA
Heavy-light decomposition
Bridges / articulation points
SCC
Euler tour technique
DSU on tree
Centroid decomposition
Minimum spanning tree
2-SAT
Virtual tree
Classical DP
Knapsack
Interval DP
Tree DP
Digit DP
Bitmask DP
Convex hull trick
Divide-and-conquer optimization
Knuth optimization
Aliens trick / Lagrangian relaxation
Monotone queue optimization
SOS DP
Rerooting DP
Slope trick
gcd / lcm
Modular arithmetic
Modular inverse
CRT
Sieve
Prime factorization
Euler phi
Mobius function
Inclusion-exclusion
Primitive roots
Discrete logarithm
Miller-Rabin
Pollard Rho
Polynomial interpolation
NTT
Prefix function / KMP
Z-function
Rolling hash
Suffix array
Suffix automaton
Aho-Corasick
Palindromic tree
Manacher
Orientation / cross product
Line intersection
Convex hull
Rotating calipers
Closest pair
Half-plane intersection
Point in polygon
Sweep line
Dinic
Min-cost max-flow
Bipartite matching
Hopcroft-Karp
Hungarian algorithm
General matching
Mo's algorithm
Sqrt decomposition
Small-to-large merging
Offline queries
Divide and conquer on answer
Parallel binary search
Randomization
Amortized analysis
Potential method
Bitset optimization
Parametric search
Raw files are still available here when you want the original TeX, C++, or statement assets.