Proof is what turns “passes the samples” into “is correct”. You don’t need full rigour in a contest, but you need the key lemma. The patterns below cover most of it.

General tools

ToolShapeTypical use
direct / loop invariantstate a property; show it holds initially, is preserved, and implies the answer at terminationbinary search, two pointers, sweeps
pigeonhole (simple) items into boxes forces one box with hashing collisions, cycle existence, 100 prisoners cycle bound
pigeonhole (generalized) items into boxes forces one box with at least one of cases must handle load
pigeonhole (averaging)if the average of values is , at least one value is (and at least one is )existence of a “good enough” element without constructing it
inductionbase case plus “smaller cases imply this one”, on size, depth, value, or number of operationsDP, tree algorithms, recursive constructions
strong induction / minimal counterexampleassume all smaller cases, or take the smallest failure and build a smaller onegraph theory, number theory
contradictionassume the property fails and derive an impossibility from optimality or an invariantgreedy optimality
constructionan explicit procedure plus proof that each step is legal, it terminates, and the output is validexistence claims
bound + constructionprove , then build a solution of value “minimum number of operations”
double countingcount one set two waysidentities, degree arguments
bijectionbuild a one-to-one map between two setsCatalan families, partition identities
probabilistic methodif a random object has the property with positive probability, one existsexistence of good colourings, hashing bounds

A loop invariant must be true mid-loop, not only at the end. For lower_bound on : everything below is and everything at or after is . Each step preserves this, and gives the answer.

Greedy

Exchange argument. Take any optimal solution . At the first place it differs from greedy, swap in the greedy choice and show the result is still feasible and no worse. By induction some optimal solution agrees with greedy everywhere.

Adjacent exchange for ordering problems. For a cost of a sequence, compare with . If the difference depends only on and , greedy sorts by the key that makes ” first” better. You must check the induced relation is a strict weak order (transitive). Example: minimise by sorting on (Smith’s rule).

Greedy stays ahead. Show that after steps greedy’s progress measure is at least as good as any solution’s after steps. Interval scheduling: the -th greedy interval ends no later than the -th interval of any feasible schedule.

Matroids. If the feasible sets form a matroid (hereditary plus the exchange property), the weight-sorted greedy is optimal for every weight function. That covers MST (graphic matroid), linearly independent sets (linear matroid), and scheduling unit jobs with deadlines (transversal/scheduling matroid). Bipartite matching is not a matroid; it’s an intersection of two partition matroids (Matroids).

Cut and cycle properties. For MST: the lightest edge crossing a cut is in some MST, and the strictly heaviest edge of a cycle is in none. Kruskal, Prim and Borůvka are all instances.

Counterexamples are part of the craft: before trusting a greedy, try to break it with 3-4 elements by brute force.

DP

  1. Say exactly what means, in words.
  2. Optimal substructure: if the part of an optimal solution inside subproblem weren’t optimal, replacing it would improve the whole. This replacement argument also tells you what the state must remember: everything the replacement could affect.
  3. Completeness: the transition enumerates every possible last (or first) decision, so the optimum is among the candidates. Soundness: every candidate is a feasible solution.
  4. Induct along a topological order of states. Check base cases and that unreachable states can’t leak in.

Where the replacement argument fails, the state is missing information. Longest simple path on a general graph depends on the set of visited vertices; on a DAG it doesn’t, so the vertex-only DP works.

DP optimisation proofs: monotonicity of the optimal split point () follows from the quadrangle inequality for . Convexity of in the number of groups justifies the Aliens trick. Both are covered in the DP chapter.

Graph algorithms

AlgorithmKey lemma
BFSvertices leave the queue in non-decreasing distance; induct on distance
Dijkstrawhen is popped, is final: any shorter path leaves the settled set through an edge to some with , and non-negative weights make the rest of the path non-negative
Bellman-Fordafter rounds, shortest walk with edges; a relaxation in round proves a negative cycle
Floyd-Warshallafter phase , is shortest using intermediates in
DFS, white-path theorem becomes a descendant of iff at time is discovered there’s a path of unvisited vertices from to ; this gives edge classification and SCC proofs
Tarjan SCC / bridgeslow-link: is the smallest discovery time reachable via tree edges then one back edge; is an SCC root iff
Topological sorta DAG has a source; removing it leaves a DAG; equivalently, reverse DFS finishing order
Max-flow = min-cutif the residual graph has no - path, the vertices reachable from define a cut whose capacity equals the flow
Kuhn / Bergea matching is maximum iff there’s no augmenting path
Königin bipartite graphs, max matching = min vertex cover (from the residual reachability of the max flow)
Halla perfect matching of the left side exists iff for every
2-SATsatisfiable iff no and share an SCC; assign true iff its SCC comes later in topological order

Data structures

  • Invariant first: heap order, BST order, “each segment tree node stores the aggregate of its range with all its ancestors’ tags applied”, “the deque is increasing”.
  • Complexity: potential functions. Splay: gives the access lemma. Segment tree beats: = number of distinct values in nodes, or the number of “tags”. Union by size: an element’s set doubles each time its root changes.
  • Randomised structures: treap depth is in expectation, by the same analysis as random BST insertion and quicksort: is an ancestor of iff it has the smallest priority among , with probability , and summing gives .

Number theory and algebra

  • Bézout: is the smallest positive integer combination . Inverses exist iff .
  • Fermat/Euler: for , because multiplying by permutes the units.
  • Lagrange: in a group, the order of an element divides the group order. This is behind primitive root tests and order-finding.
  • A polynomial of degree over a field has at most roots. That gives Schwartz-Zippel (a random evaluation catches a nonzero polynomial with probability ), the uniqueness of interpolation, and why only has roots (Miller-Rabin).
  • Deterministic Miller-Rabin for 64-bit inputs with the bases is a verified computational fact, not dependent on GRH.
  • Lucas: , so factors along base- digits.

Counting

  • Bijection: Dyck paths, binary trees, triangulations and non-crossing matchings are all Catalan via explicit maps. The reflection principle counts paths that cross a line: reflect the prefix up to the first touch.
  • Double counting: counts (set, marked element) pairs.
  • Burnside: the number of orbits is the average number of fixed points, by counting pairs with two ways.
  • Generating functions: sums of independent choices multiply; that’s a proof as well as an algorithm.
  • Sign-reversing involutions: to show an alternating sum is small, pair objects of opposite sign and count the unpaired fixed points (inclusion-exclusion, LGV lemma).

Games

  • Induct on the game tree: a position is losing iff every move goes to a winning position. Minimax is the same induction one level up: the minimax value at depth is optimal under optimal play given that the value at depth already is, bottoming out at terminal positions.
  • Alpha-beta pruning doesn’t change the answer: a branch is pruned only once its value is proven to lie outside the window that the rest of the tree could possibly use, so the pruned subtree’s exact value can never affect the final minimax value returned at the root.
  • Sprague-Grundy: a sum of games has Grundy value equal to the XOR of components. Proof: from XOR every move makes it nonzero; from nonzero there’s a move to (by the definition of mex).
  • Strategy stealing: if the first player loses, the first player can “pass” by making a move that does no harm, then steal the second player’s strategy. That’s a contradiction, so the first player wins (Hex, Chomp). It’s non-constructive.
  • Pairing / mirror strategy: pair up moves so every move has a reply that restores a symmetric or paired position.

Geometry

  • Convex hull (Graham scan / Andrew’s monotone chain): maintain the invariant that the last three points on the stack form a left turn; on a right turn, pop before pushing. Proof by orientation test at every step means the output can never contain a right turn, i.e. it is convex, and the pops never discard a true hull vertex (a popped point is strictly inside the triangle formed around it).
  • Rotating calipers: the antipodal-pair angle is monotone as the calipers rotate a full turn, so each edge direction is visited once and the total work across all antipodal pairs is , not .
  • Sweep line: process events in sorted sweep-coordinate order and maintain the invariant that the active set is exactly the structures currently intersecting the sweep line; correctness reduces to showing every structural change (an insertion, deletion, or intersection) is itself an event, so nothing is missed between events.

Lower bounds

  • Decision trees: any comparison sort has leaves, so depth . With -ary answers, queries.
  • Adversary: answer queries to keep as many inputs consistent as possible. Finding the max needs comparisons (every non-max must lose once); max and min together need .
  • Reductions (fine-grained): if solving fast would solve fast, and is believed hard (3SUM, APSP, OV), then so is . Recognising a 3SUM-hard or NP-hard problem tells you a constraint must be small.
  • Reductions (NP-hardness): rarer in CP, but recognise the shape: a polynomial-time reduction from a known NP-hard to that preserves yes/no answers proves is NP-hard too. For optimization problems, a gap reduction (distinguishing instances with value from value ) proves hardness of approximation, not just of exactness.

Backtracking and branch and bound

Correctness needs two things: the search is exhaustive (every candidate is visited if no branch is pruned, usually by induction on the decision prefix), and every prune is safe (the bounding function is a genuine upper/lower bound on anything reachable from that branch, so discarding it can never discard the optimum). A weak bound is still correct, just slow — bound quality is a performance property, not a correctness one.

Randomised algorithms

  • Las Vegas: always correct, random running time. Bound the expectation with linearity of expectation (quicksort, treaps, randomised incremental geometry via backward analysis).
  • Monte Carlo: may be wrong with small probability. Repeat to amplify, and bound the error with a union bound or Chernoff: the sum of independent indicators deviates from its mean by a factor with probability .
  • Hash collisions: with comparisons and a modulus , the failure probability is about . Polynomial hashes of length collide with probability per pair.

Habits

  • Write a three-sentence proof sketch before coding: the invariant, the exchange, or the recurrence’s meaning.
  • Prove the edge cases: , ties, empty sets, all equal.
  • Keep a list of greedy counterexamples (non-canonical coin systems, earliest-start interval scheduling, densest-first knapsack). They train scepticism.
  • When an editorial says “it’s easy to see”, find the lemma it skipped — that’s exactly the “why this works” paragraph to focus on, not the implementation details around it.
  • Explain the proof out loud, or to a teammate. Teaching exposes the gaps a silent read-through hides.

Proof discovery

Finding why an idea works, before or instead of a formal proof.

StepHow
guess with databrute force small cases, look at the optimal objects, not only the values
strengthen the claima stronger statement is often easier to prove by induction (it gives a stronger hypothesis)
look at an optimal solutionassume an optimum that differs from your greedy at the first position; can you swap it towards yours without loss? (exchange argument)
find what never changesinvariants explain impossibility and reachability
find what always improvespotentials explain termination and amortized costs
attack your own claimgenerate random and adversarial cases to break it; a counterexample is progress
prove the lower bound separately”at least ” (counting, adversary, invariant) plus “at most ” (construction)
Idea typeProof pattern
greedyexchange argument, staying ahead, matroid structure
DPstates capture everything relevant (optimal substructure); order is topological
DP optimizationquadrangle inequality / monotone argmin; convexity for Aliens and slope trick
constructionverify by a checker for all small parameters; necessary conditions match
data structureinvariant per node; amortized potential

Examples of each pattern are listed in 🐬 Proof Techniques.