Introduction
Problem E from AtCoder Beginner Contest 458 is a very typical combinatorial counting problem I encountered in a weekly contest.
On first reading the statement, it is easy to make a rough guess that permutations and combinations must be involved. But once you start deriving a solution, you find that starting directly from “all arrangements” makes the constraints awkward to handle, and a formula does not emerge so naturally.
After reviewing it, I felt that the part most worth recording was how to extract a clearer counting model from the constraints, rather than how to calculate binomial coefficients in code afterward.
This article mainly records the process from understanding the statement and modeling the structure to deriving the final combinatorial formula. Efficiently evaluating binomial coefficients does involve modular inverses, Fermat’s little theorem, and precomputed inverse factorials, but those are not the focus here; I only touch on them in the implementation section.
Modeling the Problem
The problem gives three positive integers:
We need to count sequences of length:
that satisfy:
- The sequence contains exactly copies of
1; - Exactly copies of
2; - Exactly copies of
3; - The absolute difference between any two adjacent elements is at most .
In other words, every position satisfying:
must satisfy:
The final answer is taken modulo .
Since the only elements are 1, 2, and 3, we can state the adjacency constraint more concretely. The allowed adjacent pairs are:
1 | 1-1, 1-2, 2-1, 2-2, 2-3, 3-2, 3-3 |
The only forbidden pairs are:
1 | 1-3, 3-1 |
The problem is therefore equivalent to:
Given copies of
1, copies of2, and copies of3, how many arrangements have no1directly adjacent to a3?
This makes the central restriction very clear:
A
2can sit next to either1or3, while1and3must be separated by2.
Using 2 as a Separator
Since 1 and 3 cannot be adjacent, whereas 2 can be adjacent to both, it is natural to place all the 2s first.
With copies of 2, the number of gaps they create is:
For example:
1 | _ 2 _ 2 _ 2 _ ... 2 _ |
We then only need to decide how to place all the 1s and 3s into these gaps.
There is one crucial restriction:
A single gap cannot contain both
1and3.
If a gap contains both, some 1 and 3 must become adjacent, no matter how we arrange the contents of that gap.
For example:
1 | 111333 |
has 13 in the middle.
If we write:
1 | 333111 |
there is a 31 in the middle.
Each gap therefore has only three possible states: some 1s only, some 3s only, or nothing:
1 | 只放若干个 1 |
The original arrangement problem has now become a gap-selection problem:
Among the gaps, choose some for
1and some others for3, with no overlap between the two selections.
Counting with Fixed Numbers of Gaps
Let be the number of gaps containing 1, and the number containing 3:
Once and are fixed, we can count in four steps.
Choose the Gaps for 1
There are gaps in total, and we choose of them for 1.
The number of choices is:
Here, denotes the number of ways to choose objects from .
Choose the Gaps for 3
The gaps for 1 have already occupied places, leaving:
gaps.
Since a gap cannot contain both 1 and 3, we must choose the gaps for 3 from those remaining.
The number of choices is:
Distribute the 1s Among Their Chosen Gaps
Next, distribute identical copies of 1 among the chosen gaps.
These gaps have already been designated as gaps containing 1, so each must receive at least one 1. If a gap were empty, it should not have been included in .
This step is therefore equivalent to:
Splitting identical elements into nonempty groups.
By stars and bars, the number of ways is:
To see this directly, line up the copies of 1:
1 | 1 1 1 ... 1 |
There are spaces between them. Splitting them into nonempty groups means choosing of these spaces as cuts, giving ways.
Distribute the 3s Among Their Chosen Gaps
Similarly, splitting identical copies of 3 into nonempty groups gives:
Thus, for fixed , the number of arrangements is:
The Double-Sum Formula
Next, consider the ranges of .
There are copies of 1, and each selected gap needs at least one, so:
There are also only gaps in total, so:
Hence:
For a fixed , the number of remaining gaps is:
The number of gaps containing 3 has two bounds as well:
and:
Thus:
This gives the most direct double-sum formula:
At this point, the counting model is complete.
However, directly enumerating both variables in this formula would have a worst-case complexity approaching:
The constraints are:
so a double loop is infeasible. We need to simplify away the inner sum over .
Simplifying with Vandermonde’s Convolution
For a fixed , the part of the double sum independent of is:
The part involving is:
The key to the simplification is therefore the following expression:
First, use the symmetry of binomial coefficients:
Then:
That is:
The inner sum can therefore be rewritten as:
Now we can apply Vandermonde’s convolution:
Its meaning is:
Choose a total of elements from two groups. If we enumerate the number chosen from the first group, we must choose from the second. Summing over all is equivalent to choosing elements directly from the combined groups.
Here, the correspondence is:
Therefore:
Simplify the expression inside the parentheses:
So:
Substituting this into the original double sum gives the final formula:
The double sum over has become a single sum over .
Here is the handwritten derivation:
Image legend: a: 放1 means the number of gaps containing 1, and b: 放3 the number containing 3. 提b isolates the sum over b; 即 means “that is”; 代回 means “substitute back.” The intermediate labels are and .
Evaluating the Formula and Implementing It
With the formula derived, the remaining task is to evaluate many binomial coefficients .
The answer is taken modulo , and is prime. We can therefore use Fermat’s little theorem to find inverses and precompute factorials and inverse factorials, making each binomial-coefficient query .
The implementation proceeds as follows. Precompute fac[i] = i!, then ifac[i] = (i!)^{-1}; evaluate binomial coefficients with C(n,k) = fac[n] * ifac[k] * ifac[n-k]; finally, enumerate a and accumulate contributions using the final formula:
1 | 1. 预处理 fac[i] = i! |
I will not expand on modular inverses, Fermat’s little theorem, or the binomial-coefficient template here. I plan to collect those separately in a combinatorics topic summary.
The main enumeration is:
1 | ll Ans() { |
Complexity Analysis
When precomputing factorials and inverse factorials, the largest index we need is:
The preprocessing complexity is therefore:
The final range for enumerating is:
so the enumeration takes:
Overall, the total time complexity is:
The main space cost comes from the factorial and inverse-factorial arrays:
The constraints are:
This is sufficient to pass.
Submission Record and Accepted Code
The submission record is shown below.
Expand/collapse the final accepted code
1 |
|
Closing Thoughts
The part of this problem worth reviewing is how to turn an initially awkward restriction on arrangements into a clear counting model, rather than how to evaluate binomial coefficients modulo a prime.
The derivation can be summarized in three steps:
- Recognize that the only forbidden adjacency is between
1and3; - Use
2as a separator, turning the problem into choosing gaps and forming nonempty groups; - Apply Vandermonde’s convolution to remove one level of enumeration and obtain a single-sum formula ready to implement.
The final code templates are not complicated. The difficult part comes earlier, in the modeling and derivation: identify the only forbidden adjacency, use separators to turn the conflict into gap allocation, and then use a combinatorial identity to eliminate one level of enumeration.