Problem Description
We are given an integer n representing people arranged in a line (indexed from 0 to n–1) and an array sick (sorted in increasing order) that marks the positions of people already infected. In a series of steps, one uninfected person adjacent to an infected person becomes infected. The process runs until every person is infected. An infection sequence is the order in which the initially healthy people become infected. We must count the number of valid infection sequences possible modulo 10^9+7.
Key Insights
- The infection always proceeds from an infected person to one of its adjacent uninfected neighbors.
- The line can be divided into segments: • The left boundary segment (before the first sick person), • The right boundary segment (after the last sick person), and • Interior gaps between consecutive sick people.
- For a boundary segment there is only one way to infect these people (infection propagates in one fixed order).
- For an interior segment (gap) with L uninfected people, initially both ends are available. However, the order in which the infections occur inside the gap is constrained – the infection must “peel” inward from both ends. One can show that the number of valid orders inside such a gap is 2^(L–1).
- After separately “solving” each segment (each with its internal valid order count), the overall sequence is an interleaving of the infections from all segments. The count for interleavings is given by a multinomial coefficient: if the segments have lengths L1, L2, …, Lk then the number is (Sum Li)!/(L1! * L2! * … * Lk!).
- The final answer is the product of the number of interleavings and the product of the choices for each interior segment. (Remember to take the result modulo 10^9+7).
Space and Time Complexity
Time Complexity: O(n) for precomputation of factorials up to n and processing the segments. Space Complexity: O(n) for storing factorials and inverse factorials modulo 10^9+7.
Solution
We first break the problem into parts:
- Count the total number X = n – (number of initially infected people). These are the uninfected people to be infected in some sequence.
- Determine the lengths of all segments:
- Left boundary: sick[0] (if sick[0] > 0).
- Right boundary: (n – 1) – sick[last] (if sick[last] < n – 1).
- For every gap between sick[i] and sick[i+1], the length is (sick[i+1] – sick[i] – 1). For each interior gap, there are 2^(length – 1) infection orders internally.
- Count interleavings:
- The infection order is a shuffle of the sequences from each segment. With segments lengths L1, L2, …, Lk (including boundary segments with fixed order count 1), the number of ways to interleave is (X)! / (L1! * L2! * … * Lk!).
- Multiply the interleaving count by the product of the counts for interior segments (each contributing a factor 2^(gap – 1)) and take modulo 10^9+7.
- Use modular arithmetic and precompute factorials and modular inverses for efficiency.
Data structures used:
- Arrays for storing segment lengths.
- Precomputed arrays for factorials and inverse factorials modulo mod. Algorithm:
- Compute all segments lengths.
- Precompute factorials up to X.
- Compute the interleaving count using the multinomial formula.
- Multiply by the contributions of interior segments: for each gap segment, multiply by 2^(gap_length – 1).
- Return the final answer modulo 10^9+7.
Code Solutions
Below are implementations in Python, JavaScript, C++, and Java with clear line-by-line comments.