Language details that decide correctness and speed in contests.

Integer types

TypeRange
int
unsigned int
long long
unsigned long long
__int128 — GCC only, and no cin/cout support

The overflow rule

int * int is computed as int even when assigned to a long long. Write 1LL * a * b, or make one operand long long. This is the most common wrong answer in competitive programming.

__int128 is genuinely useful for multiplying two values near modulo another, and for exact area computations in geometry. Print it by converting to a string manually.

Division and modulo of negatives

C++ truncates toward zero: -7 / 2 == -3 and -7 % 2 == -1. For a mathematical (non-negative) modulus:

int mod(int a, int m) { return ((a % m) + m) % m; }
int floorDiv(int a, int b) { return a / b - ((a % b != 0) && ((a < 0) != (b < 0))); }

Both come up constantly in grid wrap-around, modular arithmetic, and coordinate maths.

size() is unsigned

for (int i = 0; i < (int)v.size() - 1; i++)      // correct
for (int i = 0; i < v.size() - 1; i++)           // INFINITE LOOP when v is empty

v.size() - 1 on an empty vector is . Always cast, or use the sz() macro from the template.

Sorting

sort(all(v), [](const P& a, const P& b) {
    if (a.first != b.first) return a.first < b.first;
    return a.second > b.second;                   // tie-break descending
});

The comparator must be a strict weak ordering: cmp(a,a) must be false. Using <= is undefined behaviour and really does crash std::sort on large inputs — it is not a theoretical concern.

stable_sort preserves the order of equal elements; nth_element finds the -th in average.

Useful algorithms

CallDoes
lower_bound(all(v), x)first
upper_bound(all(v), x)first
v.erase(unique(all(v)), v.end())dedupe a sorted vector
next_permutation(all(v))next lexicographic permutation
accumulate(all(v), 0LL)sum — note the 0LL
__gcd(a, b)GCD (std::gcd in C++17)
iota(all(v), 0)fill with
partial_sum(all(v), out.begin())prefix sums
minmax_element(all(v))both extremes in one pass
count_if, all_of, any_ofpredicate queries

lower_bound on a set

Use the member s.lower_bound(x), not std::lower_bound(all(s), x). The free function needs random access and degrades to on a tree-based container.

Reference in range-for

for (auto& [key, val] : mp) val *= 2;        // modifies
for (const auto& s : strings) use(s);        // no copy
for (auto s : strings) use(s);               // copies every string

Copying strings or vectors in a loop is a silent constant-factor disaster.

Structured bindings and auto

auto [a, b] = make_pair(1, 2);
map<int,int> mp;
if (auto it = mp.find(k); it != mp.end()) use(it->second);

Recursion depth

The default stack is about 1-8 MB; a DFS on nodes with a large frame will overflow. Options: convert to an explicit stack, shrink the frame (avoid passing containers by value), or on Codeforces use a thread with a larger stack.

// GCC: run main work on a 256 MB stack
int main() { thread t(work, 0); t.join(); }    // or the classic setrlimit trick on Linux

Floating point

Compare with an epsilon, never with ==. Prefer exact integer arithmetic wherever the problem allows it — see Floating Point. long double gives 80-bit precision on x86 and is usually worth the switch in geometry.

Common undefined behaviour

CodeProblem
1 << 31overflow — use 1LL << 31
x << 64shift width
v[i] with i == v.size()out of bounds
a[i++] = iunsequenced modification
a comparator using <=not a strict weak ordering
signed overflowUB, and the optimiser will exploit it
reading an uninitialised variableUB, and often works locally

-fsanitize=undefined catches most of these; see Debug Macros.

See also: STL Containers · Pitfalls · I/O Optimization · Contest Template