F - Almost Sorted 2 Editorial
by
toam
\(A\) に含まれる \(v\) の個数を \(\mathrm{cnt}[v]\) とします.
条件から以下が成り立ちます.
- \(B\) において,ある要素 \(v\) の直前に \(v+D\) より大きい要素は置くことができない
この考えをもとにして,値が小さい方から \(B\) の相対的な位置を決めていく 挿入 dp でこの問題を解きます.
\(v\) 未満の相対的な位置が決まっていたとします.このとき,\(v\) を挿入できる位置は,(現在の \(B\) に依らず)\(v-D\) 以上 \(v\) 未満の数の個数に依存しています.
例えば \(D=3, B=(4, 1, 3, 5, 4, 2, 3)\) で,\(v=6\) を挿入するとき,挿入できる場所は以下のようになります:
( 4, 1, 3, 5, 4, 2, 3, )
^ ^ ^ ^ ^ ^
挿入できる箇所を数式で書くと \(\mathrm{cnt}[v-D]+\ldots+\mathrm{cnt}[v-1]+1\) 箇所です.(\(+1\) は末尾に追加できることを表しています.)
これらの挿入可能な位置から \(v\) を合計 \(\mathrm{cnt}[v]\) 個挿入する方法は,互いに区別できない \(\mathrm{cnt}[v]\) 個の玉を互いに区別できる \(\mathrm{cnt}[v-D]+\ldots+\mathrm{cnt}[v-1]+1\) 個の箱に入れる方法に等しく \(\dbinom{\mathrm{cnt}[v-D]+\ldots+\mathrm{cnt}[v]}{\mathrm{cnt}[v]}\) 通りです.
よって,求める答えは
\[\prod_{v=1}^{\max(A)}\dbinom{\mathrm{cnt}[v-D]+\ldots+\mathrm{cnt}[v]}{\mathrm{cnt}[v]}\]
です.これは \(O(N+\max(A))\) で計算できます.
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)
posted:
last update:
