[Codeforces] Edu Round 192 D — From Merging Digits to Longest Common Subsequence
Published 7 July 2026
I recently solved a Codeforces problem that taught me one of the cleanest “change your perspective” tricks I’ve seen in a while.
At first glance, the problem looks like a simulation problem.
Problem¶
We are given two strings a and b, consisting only of digits.
In one operation, we choose two adjacent digits and replace them with their sum modulo 10.
For example,
can become
because
Each operation reduces the string length by one.
We may perform any number of operations on either string.
The goal is to find the maximum possible length of the final strings after making them equal.
Observation 1: A Necessary Condition¶
Consider collapsing an entire string into a single digit.
No matter how we merge adjacent digits,
Therefore,
is a necessary condition.
If this fails, the answer is immediately -1.
Observation 2: Forget the Operations¶
Instead of thinking about individual merge operations, think about what they achieve.
Suppose we have
If we repeatedly merge only within
then eventually we obtain
The exact order of merges doesn’t matter.
Each final digit is simply the sum of one contiguous block modulo 10.
This completely changes the problem.
Instead of performing operations, we only need to decide how to partition each string into contiguous blocks.
Observation 3: Corresponding Blocks Must Match¶
Suppose
Then every corresponding block must satisfy
The answer we want is simply the maximum number of blocks.
Why?
Because every block becomes exactly one digit in the resulting string.
So
Observation 4: Add the Equations¶
Suppose
Adding them,
Continuing this,
we get
for every block boundary.
This is the key insight.
Every block boundary corresponds to a prefix sum modulo 10.
Observation 5: Prefix Sums of the Original Strings¶
Now compute prefix sums modulo 10.
For example,
and similarly for b.
Whenever the same modulo appears in both prefix sequences,
it can represent the end of a corresponding block.
Therefore, the problem becomes:
Find the largest sequence of matching prefix-sum modulo values while preserving order.
That is exactly the Longest Common Subsequence (LCS) problem.
Final Algorithm¶
-
Check whether the total digit sums modulo
10are equal.- If not, answer
-1.
- If not, answer
-
Compute prefix sums modulo
10for both strings.- Include the initial prefix sum
0.
- Include the initial prefix sum
-
Compute the Longest Common Subsequence of the two prefix-sum sequences.
-
Subtract
1from the LCS length because the initial0represents the starting boundary, not an actual block.
Overall complexity:
- Time:
O(|a| × |b|) - Space:
O(|b|)using the standard rolling-array optimization for LCS.
Takeaway¶
This problem is a perfect example of how changing the abstraction can completely simplify a problem.
Initially, it looks like a complicated sequence of merge operations.
But after identifying the right invariant, the operations disappear entirely.
The problem becomes:
- Partition into contiguous blocks.
- Convert blocks into prefix-sum constraints.
- Solve an LCS.
Those are the kinds of insights that make competitive programming so rewarding.
Bonus: Understanding the LCS Recurrence¶
Since the solution reduces to LCS, it’s worth pausing on the recurrence itself. Most of us memorize it:
But a natural question arises:
When the last characters match, why don’t we write
Just to be safe?
Let’s build the recurrence from first principles.
Step 1: Define the DP state¶
Let
represent the length of the Longest Common Subsequence between
Notice that these are prefixes of the original strings.
Importantly, the LCS does not have to include the last character of either prefix.
Case 1: Last characters are different¶
Suppose we are computing
and
The last two characters cannot both belong to the same common subsequence.
So at least one of them must be discarded.
There are only two possibilities:
- Ignore
a[i-1] - Ignore
b[j-1]
Therefore,
This part is usually intuitive.
Case 2: Last characters are equal¶
Now suppose
At first glance, it feels safer to write
Why is that unnecessary?
The answer lies in an elegant observation.
The Key Lemma¶
If the last characters are equal, then there always exists an optimal LCS that matches these two characters.
This is the crucial insight.
Why?¶
Suppose the common character is x.
There are two possibilities.
Case A¶
The optimal LCS already uses these last two xs.
Great—we’re done.
Case B¶
The optimal LCS matches an earlier occurrence of x.
For example,
Maybe the LCS matched the first x.
But notice something:
Everything that appears before the first x also appears before the last x.
So we can simply replace the earlier matched x with the later one.
The order of the subsequence is preserved.
The length does not change.
In other words, we can always “shift” the match to the last occurrence.
This is a classic exchange argument.
Therefore, there is always an optimal solution that ends by matching
Finishing the recurrence¶
Once we’ve matched the last characters,
we remove them from both strings.
What’s left?
Exactly the LCS of
whose length is
Therefore,
But what if dp[i-1][j] is larger?¶
This is the part that often feels mysterious.
Suppose
Could
actually be larger?
The answer is no.
Why?
Adding one extra character to a string can increase the LCS by at most one.
So,
Similarly,
But
is exactly the value we compute when the last characters match.
Therefore,
Neither of the other two transitions can produce a better answer.
Taking the maximum is unnecessary.
Intuition¶
I like to think about it this way:
When the last characters are equal, you’ve been handed a free match.
Ignoring it can never help.
Even if an optimal solution used an earlier occurrence of A, you can always move that match to the last A without breaking the order of the subsequence.
So matching the last equal characters is never a mistake—it is always part of some optimal solution.
Final Recurrence¶
This recurrence is not just something to memorize.
It follows from two ideas:
- If the last characters differ, one of them must be discarded.
- If the last characters are equal, there always exists an optimal solution that matches them.
Once you understand these two observations, the LCS recurrence becomes something you can derive rather than remember.