この記事で使うアルゴリズム
逆元
はじめに
カテゴリー競プロ初中級者100問では、Qiita
にて@e869120
さんがレッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】としてまとめられている100問をPython
で解いています。
全問題の一覧はこちらです
問題
https://atcoder.jp/contests/abc021/tasks/abc021_d
この問題では逆元の計算が求められます。
方針
準備運動として、下記の組み合わせの数え上げについてを考えます。
1 | 1 <= a_1 < a_2 < ... < a_k <= N |
少し考察すると、これはN個の要素の中から重複せずにk個の要素を取り出すパターン数
、すなわちn_C_k
と等価であることがわかります。
そのように理解すると、本題の
1 | 1 <= a_1 <= a_2 <= ... <= a_k <= N |
はN個の要素の中から重複を許してk個の要素を取り出すパターン数
であることがわかります。これは重複組合せと呼ばれる概念で、
1 | n_H_k = (n-1+k)_C_k = (n-1+k)!/((n-1)!k!) |
を計算すれば良いです。
階乗の部分が巨大になるため、計算途中で剰余の計算を行います。しかしながら、除算が含まれるため逆元と呼ばれる概念を導入する必要があります。
逆元については以下の問題の解説をご覧ください。
コード
1 | MOD = 10**9+7 |
記事情報
- 投稿日:2020年5月3日
- 最終更新日:2020年5月8日