The Two Types of Contiguous Segments
CCPC 2021 Online H - Subpermutation defines the full-permutation of : concatenate all permutations of through in lexicographic order to obtain the sequence .
Given , count the contiguous subsequences of of length that are themselves permutations of through . Answers for multiple test cases are taken modulo , with:
Each original permutation has length , and the segment length does not exceed . A segment can therefore meet at most two original permutations, and all cases split completely into two types:
- The segment lies entirely within one permutation;
- The segment takes a nonempty suffix of one permutation followed by a nonempty prefix of the next.
These two types are disjoint, so count them separately and add the results.
Contributions Within One Permutation
A contiguous segment of length is a permutation of through if and only if those values occupy consecutive positions in the current permutation.
First choose the starting position of this block, giving choices. The values through can be arranged arbitrarily inside the block, and the remaining values can also be arranged arbitrarily. The total number of valid segments lying entirely within a single permutation is therefore:
This counts across all permutations together. Each permutation satisfying the condition contributes exactly one valid starting position, with no duplication.
Crossing a Permutation Boundary
Fix the length taken from the end of the preceding permutation as , where:
Let , and split the preceding permutation by position into:
Here, , , and . The segment crossing the boundary consists of followed by the length- prefix of the successor permutation .
First, require only that and together contain exactly the values through . Then:
- The values through can occupy the positions of in any order, giving choices;
- The values through can occupy the middle part in any order, giving choices.
The number of candidate permutations is:
We still need to determine whether prefix stays unchanged when moving from to its lexicographic successor .
The Subtraction Term from the Longest Decreasing Suffix
To find a permutation’s lexicographic successor, locate its longest decreasing suffix, swap the pivot immediately before that suffix, and put the suffix into its smallest, ascending order.
If is not decreasing, the pivot must lie within , so the length- prefix remains unchanged. The segment crossing the boundary is then , containing each value from through exactly once, and is valid.
Conversely, if all of is decreasing, the lexicographic-successor operation crosses the boundary between and . The first entries of the successor are no longer exactly the original : an element originally to the right of that boundary moves into the prefix. If is already the last permutation, it has no successor at all. In either case, and the new prefix can no longer form exactly a permutation of through .
We therefore only need to subtract the cases where all of is decreasing from the candidate count.
Every value in is greater than , while every value in is at most , so their boundary is already decreasing. For all of to be decreasing, it is enough for and each to be in descending order:
- Choose the values of from through , giving choices. Once chosen, their descending order in is unique;
- Arrange the remaining values arbitrarily in , giving choices;
- The descending order of is unique.
The subtraction term is therefore:
For fixed , the number of valid segments crossing a boundary is:
Summing over all :
Combining the Counts into a Closed Form
Add the contributions from within permutations and across their boundaries:
Ultimately, we need only factorials, inverse factorials, and prefix sums of inverse factorials.
Let:
In the implementation, fac[i], ifac[i], and sum[i] maintain , , and , respectively. Each query directly evaluates:
1 | return (1ll * n * fac[n - m] % mod - sum[m - 1] + mod) % mod * fac[m] % mod; |
All divisions here use modular inverses modulo . The preprocessing range is below the modulus, so every factorial has an inverse.
When , the sum is empty and sum[0]=0. The formula gives , exactly the number of occurrences of 1 in the full sequence. When , fac[n-m]=fac[0]=1, so the same formula works without an additional branch.
Complexity and Implementation Boundaries
Precompute factorials, inverse factorials, and prefix sums up to . This takes time and space. After preprocessing, each query performs only a constant number of modular operations, taking per query and for all queries.
Three implementation boundaries must also remain consistent:
- Set
fac[0]=1, so is available directly when ; - Start the inverse-factorial prefix sum at
ifac[1], so the subtraction term is empty when ; - For modular subtraction, add
modbefore taking the remainder to avoid a negative intermediate result.
Final Accepted Code
Expand/collapse the final accepted code
1 |
|