Before submitting

  • Samples pass — all of them, including any in the notes
  • Edge cases: , , all equal, all negative, maximum values, disconnected
  • long long wherever a product can exceed
  • Modulus applied after every addition and multiplication
  • Subtraction under a modulus normalised: ((a-b) % M + M) % M
  • Globals cleared between test cases
  • Array sizes correct (n+1, not n)
  • Indexing consistent (0-based or 1-based)
  • Recursion depth under
  • Output format exact — precision, “impossible” sentinel, newlines
  • Complexity checked against the constraints
  • Memory estimated

Overflow checklist

  • int * int overflows before assignment to long long — write 1LL * a * b
  • Graph distances almost always need long long
  • mid = (l + r) / 2l + (r - l) / 2
  • i * i <= ni <= n / i
  • Products near __int128
  • Prefix sums of values up to reach

Graph checklist

  • Directed or undirected?
  • Weighted or unweighted? Negative weights?
  • Connected, or multiple components?
  • Self-loops or parallel edges?
  • Is it a tree, DAG, bipartite, or general?
  • Do you need a path, a count, or just a distance?
  • Is or the binding constraint?

DP checklist

  • What exactly is the state? Is it complete? Is it minimal?
  • Are the transitions acyclic (is the evaluation order valid)?
  • Base cases: unreachable states initialised to , not 0?
  • Is a modulus required?
  • Max, min, count, or probability?
  • Does order matter — are you over- or under-counting?
  • Knapsack: weight loop downward for 0/1, upward for unbounded
  • Coin change: coins outside for combinations, amount outside for permutations
  • Can the state be compressed? Is memory within limits?

Binary search checklist

  • The predicate is defined precisely
  • It is monotone — verify against a brute force if unsure
  • The bounds provably contain the answer
  • First-true or last-true chosen deliberately
  • Real-valued search uses a fixed iteration count, not an epsilon condition

Geometry checklist

  • Integers wherever possible; squared distances for comparisons
  • One epsilon, scaled to the coordinate magnitude
  • Degenerate cases: collinear, duplicate points, , zero-length segments
  • Orientation convention fixed (CCW positive) and polygons normalised
  • Cross products checked for overflow

Contest debug checklist

  • Edge cases: n=0, n=1, all equal, all negative, disconnected, impossible
  • 0-based vs 1-based indexing
  • Global arrays cleared between tests
  • Parent / visited arrays initialised
  • Modulus after every operation
  • Sorted before binary search or two pointers
  • Recursion depth over → iterative

Interactive problems

  • Flush after every query (endl, or cout << flush)
  • Read the response before the next query
  • Respect the query limit
  • Handle the “you are wrong” response if the protocol has one
  • Test against a locally written interactor

The template header

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int T = 1;
    // cin >> T;
    while (T--) solve();
}

Check whether the problem has multiple test cases before writing the loop — and if it does, make sure everything is reset inside solve().

Useful pragmas

#pragma GCC optimize("O2,unroll-loops")
#pragma GCC target("avx2,popcnt")

Legitimate on Codeforces and often a 2-4× speedup for tight loops and bitset work. Check the judge allows them.

Time management

SituationAction
Stuck 15+ minutes with no ideaswitch problems
Idea but messy implementationlook for a simpler formulation
Two wrong answers on the same problemstress test before a third submit
30 minutes leftsecure existing solutions, do not start something new
Everything solvedre-check the risky ones

See also: Common Pitfalls · CP Workflow · Debugging