Educational Codeforces Round 83 D
内容
- EC R-83 D問題 Count the Arraysをpythonでと解きました。
問題
以下の条件を満たす配列 A の数を求める
- len(A)=N
- Aの要素は [1,M]
- ちょうど一つ、等しい数のペアを含む
- あるインデックス iが存在し、1~iまでは単調増加、i~Nまでは単調減少となる
入力
- N:配列の長さ
- M:配列の数字の上限
出力
- 条件を満たす配列の数を、mod 998244353 したもの
ポイント
Aに含まれる数字の選び方 : MC(N-1)
- Aには、N-1個の独立した要素が含まれる。
- ちょうどひとつ、等しい数字のペアがあるから。
- Aには、N-1個の独立した要素が含まれる。
- 2回現れる数字の選び方 :(N-2)通り
- 2回現れる数字はMではない。
- 最大の数が2回現れると、単調増加・減少の条件を見たせない。
- 2回現れる数字はMではない。
- 並び方: 2N-3通り
- 選んだ数字を、折り返し地点iより右か左かに分ける(2回現れる数字以外でN-3個)
- 2回現れる数字は、左右に一つずつ。
- 左側は昇順、右側は降順に並ぶため、並べ方は一通りに決まる
- 選んだ数字を、折り返し地点iより右か左かに分ける(2回現れる数字以外でN-3個)
よって、MC(N-1)(N-3)nN-3のmodを取ったものが答えとなる。 (注)N=2のときは、2N-3の計算が辛いので、別途処理する。
実装
# -*- coding: utf-8 -*- class FactMod(): #よく使う逆元のやつ def __init__(self, n, mod): self.mod = mod self.f = [1]*(n+1) for i in range(1, n+1): self.f[i] = self.f[i-1]*i % mod self.inv = [pow(self.f[-1], mod-2, mod)] for i in range(1, n+1)[::-1]: self.inv.append(self.inv[-1]*i % mod) self.inv.reverse() def comb(self, n, r): ret = self.f[n] * self.inv[n-r]*self.inv[r] ret %= self.mod return ret N, M = map(int, input().split()) MOD = 998244353 F = FactMod(M, MOD) if N == 2: print(0) else: ans = F.comb(M, N-1)*(N-2)*pow(2, N-3, MOD) % MOD print(ans)
終わりに
- 解説AC
最近買ったもの
- モニターがある生活は強い。