Level 0 Training
Your foundation in C++ and competitive programming. From your first program to efficient range queries, build understanding one small step at a time.
Programming foundations
Turn a problem statement into a working C++23 program. Learn input, data types, safe arithmetic, decisions, loops, and the habits that make a solution correct.
From a problem to a program
Identify the input, output, and constraints, then translate a small plan into C++.
Variables, types, and remembered values
Choose a representation, initialize it, and understand what assignment really changes.
Arithmetic without surprises
Predict division and remainder, widen before multiplication, and format decimal answers.
Conditions and logical decisions
Build exclusive categories, combine comparisons, and protect operations with short-circuit logic.
Optional: other ways to choose
Recognize switch for exact choices and the conditional operator for choosing a value.
For loops: make repetition precise
Trace initialization, condition, body, and update—and avoid an extra iteration.
While, do-while, and stopping rules
Choose a loop from its stopping condition and read the exact input format.
Break, continue, and early answers
Distinguish leaving a loop from skipping one iteration, without losing required input.
Five patterns worth understanding
Use sums, counts, best-so-far candidates, products, and flags to process a stream.
Nested loops: rows and columns
Translate a shape into two loop roles and count the total work.
Take a number apart, one digit at a time
Use remainder and division to process decimal digits, including zero.
Multiple cases and a debugging mindset
Combine the patterns, isolate each case, and test the boundaries that can break your idea.
Arrays & strings
Store and revisit values, work with rows and columns, and treat text as a sequence of characters. Build safe scans, searches, transformations, and small state machines.
Arrays: give every value a place
Understand indices, initialization, capacity, active length, and the first safe array loop.
Scan, count, search, and compare
Distinguish values from positions and preserve the exact tie rule a problem asks for.
Change a sequence without losing it
Update, copy, compare, reverse, and inspect neighbours using the correct bounds.
Matrices: think in two coordinates
Traverse tables, total rows and columns, inspect diagonals, and protect grid neighbours.
Characters become strings
Separate characters from numbers, then safely inspect and edit managed text.
Read the text the problem actually gives
Choose words or full lines, preserve empty cases, and reset only the state that needs it.
Scan text: count, filter, transform
Build a result from matching characters without losing leading zeros or skipping shifted text.
Join, compare, and find text
Learn content comparison, lexicographical order, substring counts, and the not-found sentinel.
Mirror pairs and common beginnings
Check palindromes and shared prefixes without changing the text or crossing its boundaries.
Word boundaries and reliable text tests
Remember whether you are inside a word, then use small boundary cases to audit a scan.
Optional: rearrange an active sequence
Use half-open algorithm ranges and preserve values while shifting, rotating, inserting, or deleting.
Optional: subsequences and useful tools
Distinguish consecutive pieces from ordered selections, then recognize safer library conveniences.
Functions & complexity
Build reusable C++ helpers, make their contracts explicit, and count time and memory before the input gets large.
One function, one clear job
Follow a call from its arguments to its return value, and distinguish declarations from definitions.
Return, print, and start fresh
Use return values, void actions, early exits, and local scope deliberately.
Copies, references, and side effects
Predict whether a function can change its caller by reading its parameter types.
Array helpers need a contract
Pass an active length, protect read-only inputs, and define missing results and tie rules.
Strings and small helper teams
Read strings without copying, return transformed values safely, and compose helpers with clear tests.
Describe growth with Big-O
Name the input sizes and separate operation counts, growth bounds, and actual runtime.
Look past the number of loops
Count rectangular, triangular, shared-counter, and growing-chunk loops correctly.
Halving and square-root work
Recognize logarithmic progress and build a prime test with a safe inclusive boundary.
The work hidden in a call
Include copied parameters, helper bodies, string operations, and input/output in your estimate.
Memory, limits, and many test cases
Count peak live storage and total work across cases before choosing an algorithm.
Optional: more expressive interfaces
Explore overloads, default arguments, and fixed-width matrix parameters after mastering ordinary calls.
Optional: recursion and pending work
Trace a base case, the return journey, total calls, and peak call depth.
STL: sequences & adaptors
Learn vector, pair, deque, queue, priority_queue, and stack through state changes, ordering rules, and the cost of each operation.
Meet your standard-library toolkit
Choose an interface by the next operation you need, and construct vectors with the intended contents.
Vector elements, size, and room
Traverse safely and distinguish existing elements from reserved storage.
Iterators, edits, and invalidation
Use half-open ranges and reason about positions after structural changes.
Algorithms over a range
Sort, reverse, search, sum, remove, and deduplicate with the right return types and costs.
Vectors in functions and grids
Choose copies or references deliberately and traverse nested vectors without assuming every row matches.
Pairs and precise tie rules
Keep related values together and make ordering requirements explicit.
Deque: work at either end
Keep recent arrivals and make front/back updates without repeated vector shifts.
Queue: serve the oldest first
Model FIFO commands, repeated turns, copies, and fresh state between test cases.
Priority queues: choose the next extreme
Use max-heaps, min-heaps, and pair priorities without confusing heap order with full sorting.
Stack: resolve the newest first
Learn LIFO and use it to check all three kinds of bracket nesting.
Cancellation, undo, and combined tools
Use a reduced-prefix invariant, preserve action history, and combine a queue with a stack.
Optional: keep only the best k
Use a small min-heap to retain the largest arrivals, and justify the invariant and costs.
Sets & maps
Choose between distinct keys, repeated items, key–value records, and dynamic ranks. Trace the state, make safe updates, and count the real cost.
Think in keys, not positions
Choose a representation, build a set, and ask whether a key exists.
Walk and erase safely
Understand iterators, extremes, references, and deletion loops.
Find the nearest valid key
Translate thresholds into lower bounds, upper bounds, and predecessors.
Every copy counts
Use multisets to represent stock and sell exactly one affordable item.
One key, one record
Use maps without confusing lookup, insertion, and replacement.
Counts, ties, and groups
Build frequency maps, resolve ties, and preserve occurrence positions.
Hashing and exact-key queries
Understand unordered maps, deterministic output, and average versus worst-case cost.
Ask the past before adding the present
Solve two-sum safely and choose a container by required operations.
Ranks with a GNU ordered set
Count smaller keys and select a zero-based rank efficiently.
Ranks change; identities do not
Update ranked sets and optionally preserve duplicate occurrences with IDs.
Optional: combine and compare keys
Use composite keys, set intersections, and explicit ordering rules.
Make the state tell the truth
Maintain active frequencies, reset test cases, and debug the representation first.
Static range queries
Build prefix totals, count bounded values, and record range additions at their boundaries. Extend the same reasoning to substrings, grids, and layered queries.
Build once. Query many times.
Derive prefix sums from their meaning and cancel the unwanted beginning.
Safe sums and honest complexity
Choose wide types, avoid query-time copies, and recognize stale summaries.
Transform the question into a sum
Count conditions, evaluate fixed windows, and compare both sides of a pivot.
Count values with direct indexing
Size the domain, handle signed keys with offsets, and find a mode.
Letters and equal pairs
Preserve multiplicity in a small alphabet and count pairs as they arrive.
Which axis are you prefixing?
Count values in a numeric interval or letters inside a substring.
Add to a range with two markers
Record boundary changes and reconstruct all values after the updates.
Build a pipeline of summaries
Combine initial values, offline additions, coverage conditions, and final queries.
Prefix sums in two dimensions
Use inclusion-exclusion for rectangles and marked-cell counts.
Optional: different kinds of totals
Use numeric helpers correctly and derive weighted or modular prefix formulas.
Optional: sparse values and rectangle updates
Compress an enormous value domain or extend difference markers to a grid.
Optional challenge: find matching prefixes
Count target-sum subarrays and verify every summary against its meaning.