barrett@ruth:~$ /algorithms

Competitive Programming Log

the beginning—12/2/2025

This marks the (true) beginning of my competitive programming journey. By "true" I mean intentional, focused, daily practice. Driven by my admiration for competitive programmers, love of challenge, and desire for a decent new-grad job, I'm excited to start putting in the work.

This webpage will be an archive of everything related to this process, including my practice strategies, setup, shortcomings, logs, and more. For now, I'll be practicing on CodeForces (account sigill) and CSES, using the CP Handbook and browsing by related problem tags with ever-increasing difficulty.

938 (div. 3)—15/2/2025

What would've been my best contest. Unfortunately, CodeForces decided to go down for TREE[3] centuries, which absolutely ruined my groove in the contest and terminated my virtual. No excuses, though, as I set a timer and finished up later.

A

Brute-forced it but it still took me a few minutes.

  • Read (and exploit) problem constraints
  • Go back and derive the linear optimization (choosing the one with better marginal utility)
  • If you have a (simple enough) solution, just go with it.

B

Easily recognized how to form the matrix (i.e. smallest element first with positive integers \(c,d\)) but tripped up on the implementation.

  • Flesh out the steps before coding (i.e. walk through iterations in head, transitions, edge cases on the rows and columns, i.e. checking if i==n-1) especially on implementation-heavy problems

C

Did a horrific (but correct) binary search solution. Tripped up by specifics of std::{upper,lower}_bound regardless. Technically, generating the prefix and postfix arrays takes two passes and two binary searches to find the answer but this is still more inefficient than the trivial linear scan.

  • THE INT OVERFLOW INCIDENT
  • Deepen understanding of binary search & STL functions to the point that it is second nature
  • Consider simple solutions first.

D

Instantly recognized sliding window but struggled with minor details (i.e. keeping track of match count) by rushing to the solution.

  • Problem statement took a long time to grasp. Look at examples and just read through slower (don't rush!)
  • Sliding window grasp isn't rigorous—improve this later
  • When you don't remember 100% of how an algorithm works, mentally walk through a few iterations
  • Improve PBDS API familiarity (practice)

E

I had mentally tapped out by this point (I submitted a TLE \(O(n^2k)\) solution without using my brain). I solved F first, then took a look at G before coming back to E, robbing me of 10 minutes that could've been the difference between another solve.

  • You're not like that. Solve problems in order (most of the time, although skipping to F first was a wise decision).
  • Consider ideas fully before dropping them. I considered the difference array, then discarded it, erroneously believing a boolean was sufficient and completely forgetting that the concept of ranges complicates flipping.
  • Formalize constraints more clearly to help form a solution. For example, the idea that flipping things twice makes no difference, permitting the use of a boolean difference array.
  • Prove correctness. I didn't prove that iterating left to right, toggling a range of k actually would always give a correct answer.

F

Had the solution quickly but overcomplicated the implementation. Walked through the examples and took my time.

  • Failed to formalize the answer to the problem. I noticed patterns but should've strictly defined the following rule: "Every even count of a number contributes one to the score. Further, one triple of 1, 2, 3 also contributes one." Ultimately, I ended up submitting something I wasn't certain would be correct.

G

Wasted time believing this was primitive DP, when it totally wasn't.

  • You're not that guy (yet >:))
  • Prove optimal substructure and overlapping subproblems before using DP & walk through the test cases. In this case, test case 3 immediately disproves dp.

cses—21/2/2025

Everyone recommends CSES so I started with it, doing the first 8 problems.

weird algorithm

Trivial, but I forgot to print 1 at the end.

Return the exactly correct answer.

missing number

N/A

repetitions

Use invariants.

increasing array

Run through one iteration of the algorithm. Here, I erroneously added x - last to a quantity, after manipulating x.

permutations

I'd seen this problem before yet struggled. Fully understand the problem constraints. In this case, While I understood the definition of a permissible permutation, I didn't fully internalize that you could place number wherever you want. Instead, I was locked in on placing some x at i, i + 2, i + 4, .... Further, the fact that I didn't immediately recognize this solution means I need to improve at upsolving and reviewing problems.

permutations

Absolutely disastrous. I continually just f*dged with the offsets I was adding to my strategy until I happened to get the answer right. Don't guess. Also, don't be lazy—if an algorithm works, focus, write it out, and enjoy being correct.

two knights

Required 2 hints from Sam Altman. git gud at combinatorics. Use the paradigm "count good, remove bad." Lock in less on counting specifics—instead, consider what objects mean in aggregate. In this case, a \(2\times3\) grid represents an "area" of attack, contributing 2 bad knight pairs. This is much easier to digest then attempting to remove overcounting per-knight. Fundamentally, the problem involves placing 2 knights, so breaking it down 2 knights at a time is the most intuitive take.

two sets

Don't lock in on one approach. Here, this is dp. The fact that I knew the idea of partitioning the first \(n\) numbers into two groups of size \(\frac{n(n+1)}{4}\) but failed to recognize the greedy approach means I didn't grasp the fundamental arithmetic of the problem, nor the greedy idea: every number must go into a set. If you add the largest number possible to set 1 to not exceed the target, this number can always be formed in the other set by choosing \(1\) and \(x-1\). git gud at greedy.