F - Almost Sorted 2 解説 by en_translator
Let \(\mathrm{cnt}[v]\) be the number of \(v\) contained in \(A\).
The condition in the problem imposes the following constraint:
- In \(B\), one cannot place an element greater than \(v+D\) right before an element \(v\).
Based on this idea, we try to solve the problem with Insertion DP (Dynamic Programming), where we determine the relative positions in \(B\) of the elements, one-by-one in ascending order.
Suppose that the relative positions of elements less than \(v\) have been already determined. Then the positions where \(v\) can be inserted solely depends on the number of elements between \(v-D\) (inclusive) and \(v\) (exclusive), regardless of the actual current contents of \(B\).
For example, if we have \(D=3\) and \(B=(4, 1, 3, 5, 4, 2, 3)\), and we are to insert \(v=6\), the positions where it can be inserted are:
( 4, 1, 3, 5, 4, 2, 3, )
^ ^ ^ ^ ^ ^
The number of slots can be written as \(\mathrm{cnt}[v-D]+\ldots+\mathrm{cnt}[v-1]+1\). (We have \(+1\) because we can insert at the end.)
The number of ways to insert \(\mathrm{cnt}[v]\) copies of \(v\) into these slots equals the number of ways to put indistinguishable \(\mathrm{cnt}[v]\) balls into distinguishable \(\mathrm{cnt}[v-D]+\ldots+\mathrm{cnt}[v-1]+1\) boxes, so the count is \(\dbinom{\mathrm{cnt}[v-D]+\ldots+\mathrm{cnt}[v]}{\mathrm{cnt}[v]}\).
Therefore, the sought answer is
\[\prod_{v=1}^{\max(A)}\dbinom{\mathrm{cnt}[v-D]+\ldots+\mathrm{cnt}[v]}{\mathrm{cnt}[v]},\]
which can be evaluated in \(O(N+\max(A))\) time.
mod = 998244353
table_size = 3 * 10**5
fac = [1] * (table_size + 1)
finv = [1] * (table_size + 1)
for i in range(2, table_size + 1):
fac[i] = fac[i - 1] * i % mod
finv[table_size] = pow(fac[table_size], mod - 2, mod)
for i in range(table_size - 1, -1, -1):
finv[i] = finv[i + 1] * (i + 1) % mod
def binom(n, k):
if n < 0 or k < 0 or k > n:
return 0
return (fac[n] * finv[k] % mod) * finv[n - k] % mod
N, D = map(int, input().split())
A = list(map(int, input().split()))
cnt = [0] * (max(A) + 1)
for i in A:
cnt[i] += 1
ans = 1
s = 0
for i in range(max(A) + 1):
s += cnt[i]
ans *= binom(s, cnt[i])
ans %= mod
if i >= D:
s -= cnt[i - D]
print(ans)
投稿日時:
最終更新: