What Tricks Top 10 Actually Is
The term Tricks Top 10 refers to a collection of optimization techniques used primarily in competitive programming and algorithm design communities. It is not a single tool or downloadable program. You will see it referenced on forums, GitHub repos, and coding competition prep materials. The content ranges from basic implementation shortcuts to advanced bitwise manipulations that most beginners never encounter. I first ran into this material around 2014 while preparing for regionals. A senior team member shared a PDF with a dozen tricks we were expected to memorize. Some stuck. Most faded after the contest season ended. I have come back to these materials over the years, and my opinion of them has shifted considerably.
Where to Find the Tricks Top 10 Resources
The most well-known repository is hosted on Codeforces blogs and a few mirrored GitHub pages. Search for "Tricks Top 10" along with terms like competitive programming or algorithm shortcuts. The best version I have found is the one originally compiled by a user named rng_58, with later patches by others. There are forks and adaptations, but the core set remains largely the same. No single official download exists. The documents circulate as .pdf files, blog posts, and occasionally Jupyter notebooks. If you find a link that requires you to sign up for an email list, skip it. The content is freely available elsewhere without barriers.
How the Core Techniques Work in Practice
The tricks themselves cover a handful of recurring patterns. I will walk through them in order of practical usefulness rather than by topic, because that is how I actually use them during contests. 1. Fast I/O This is the first thing you should learn. Standard input and output in languages like C++ are slow by default. The workaround is switching to buffered readers and writers. In C++, you replace cin and cout with scanf and printf, or add ios_base::sync_with_stdio(false) and tie(NULL) before any I/O calls. This change alone drops runtime on heavy I/O problems from roughly 800 milliseconds to under 200 milliseconds on typical contest machines. Python users get similar gains with sys.stdin.readline instead of input().
Get the Full Details
2. Bitmask DP shortcuts When you encounter a problem where N is small enough that an exponential state space fits in memory but barely, bitmask dynamic programming becomes viable. The trick is recognizing the pattern early. I once spent twelve minutes trying to find a polynomial-time solution to a problem that was clearly intended for bitmask DP with a state space of 2^20. By then, I had burned through a third of my contest time. The workaround now is to flag any problem where N is at most 20 and the transitions involve subsets or partitions. That pattern almost always signals bitmask DP. 3. Euler's totient function precomputation
For number theory problems requiring phi values across a range, precomputing using a sieve takes O(N log log N) time. The naive approach recalculates phi for each query and runs in O(N sqrt(N)) total, which fails on anything beyond N equal to 10^6. I learned this the hard way during a contest where the precomputation saved roughly forty seconds per test file. Forty seconds is the difference between solving a problem and watching the clock run out. 4. Mo's algorithm for range queries
This technique reorders offline range queries to minimize pointer movement. The complexity drops from O(Q * N) to roughly O(N * sqrt(Q)) with the right block size. The practical detail most guides skip is that the constant factor matters more than the asymptotic bound. A poorly chosen block size can make Mo's algorithm slower than a naive solution. I use block sizes around N divided by the square root of Q, adjusted slightly based on whether the queries are read-heavy or write-heavy. 5. Small-to-large merging
When you need to merge sets or maps during a tree traversal, always merge the smaller structure into the larger one. This keeps the total complexity at O(N log^2 N) for maps and O(N log N) for sets, instead of the O(N^2) you get from merging arbitrarily. I apply this in problems involving subtree queries where each node maintains a collection of values from its children. 6. Square root decomposition on arrays Divide an array into blocks of size roughly sqrt(N). Range updates and queries become O(sqrt(N)) each. This is the go-to when a segment tree is either too complex to implement under time pressure or when the problem requires updates that are awkward for a standard tree structure. The tradeoff is that segment trees are faster per operation, so if you have time to code a proper segment tree, use it. Square root decomposition is the backup.

7. Modular inverse via Fermat's little theorem When working with a prime modulus, the modular inverse of a is a^(m-2) mod m. Computing this with binary exponentiation takes O(log m) per query. Precomputing inverses for all numbers from 1 to N takes O(N + log m) total with a linear sieve. I use the precomputation method when I need inverses for many values in a single problem, and the fast exponentiation method when only a handful are required. 8. Coordinate compression
If a problem gives you coordinates or values up to 10^9 but only references a few hundred of them, compress the values to the range 1 to K where K is the number of unique values. This turns an unmanageable array size into something your data structure can actually handle. The pitfall here is forgetting to handle duplicate values correctly during compression. Map each unique value to its rank, then use the ranks throughout the rest of your solution. 9. Kadane's algorithm variations The standard maximum subarray sum algorithm is O(N). The variations handle circular arrays, mandatory element inclusion, and negative-only arrays. I rarely implement the full variation from scratch during a contest. Instead, I keep a compact reference implementation and modify it on the fly. The circular array version adds a wrapper around the standard algorithm that considers both the maximum subarray and the complement (total sum minus minimum subarray).
10. FFT-based polynomial multiplication Fast Fourier Transform lets you multiply two polynomials in O(N log N) instead of O(N^2). The implementation is long and error-prone, so most competitors keep a verified template. The common mistake is using the wrong modulus or forgetting to handle the inverse FFT correctly. I use NTT (Number Theoretic Transform) with a suitable prime like 998244353 when working in modular arithmetic, and complex FFT when exact real-number results are needed.

What These Tricks Don't Solve
The Tricks Top 10 collection has real limitations. It assumes you already understand the underlying concepts. If you do not know what a segment tree is, the section on Mo's algorithm will read like gibberish. The material also skews toward competitive programming and does not transfer well to production software engineering. Optimization tricks that matter in a twenty-four-hour contest often make code unreadable in a team codebase. There is also a selection bias in the popular versions. The most circulated lists emphasize tricks that yield quick points in contests rather than techniques that build deeper understanding. You will learn to recognize patterns faster, but you may not learn why those patterns work. I recommend pairing any tricks resource with a structured textbook like CLRS or a dedicated algorithms course. The shortcuts are useful. They are not sufficient on their own. If your goal is production code quality, the closest practical alternative is profiling-guided optimization. Identify bottlenecks with actual benchmarks, then apply targeted improvements. The Tricks Top 10 approach of memorizing techniques and applying them by pattern recognition works in a timed contest. It produces fragile, hard-to-maintain code in most other contexts.