はじめに
AtCoderの過去問(ABC145 - D)を解いていたらnCk mod p を求める必要があって苦戦した。
そこで よくやる二項係数 (nCk mod. p)、逆元 (a^-1 mod. p) の求め方 をRubyで書き換えた、簡単に使えるModCombinationクラスをここに残そうと思う。
コード
class ModCombination
def initialize(max)
@MOD = 10 ** 9 + 7
@fact = [1, 1]
@factinv = [1, 1]
@inv = [0, 1]
2.upto(max) do |i|
@fact << @fact[i-1] * i % @MOD
@inv << @MOD - @inv[@MOD % i] * (@MOD / i) % @MOD
@factinv << @factinv[i-1] * @inv[i] % @MOD
end
end
def com(n, k)
return 0 if n < k
return 0 if n < 0 || k < 0
return @fact[n] * (@factinv[k] * @factinv[n-k] % @MOD) % @MOD
end
end
使い方
-
MOD
が $ 10^9 + 7 $ 以外だったら@MOD
の値を書き換える -
com(n, k)
でnCk % MOD
が求まる
max = 10 ** 6
comb = ModCombination.new(max)
puts comb.com(n, k) # nCk mod 10 ** 9 + 7
おわりに
上のコードが何をやっているかは調べれば出てくると思うので割愛する。
この記事が誰かのACに繋がればと思う。