Large nCr Small Modulus

2 secs 1024 MB
143-378's icon 143-378

解説

各素因数ごとに 一般化Lucasの定理(NR)\binom{N}{R} modmod PiEiP_i ^ {E_i}を計算し、中国剰余定理で解を復元します。
一般化Lucasの定理の詳細は参考文献をご覧ください。
計算量は前計算O(M)O(M)時間・空間、クエリO(logNlogM+logM)O(logNlogM + logM)時間になります。
内訳は以下の通りです。

  • 前計算では、PiP_iの倍数を除いた階乗x!Pix!_{P_i} modmod PiEiP_i ^ {E_i}PiEiP_i ^ {E_i}まで計算すればよいです。
    計算量は時間・空間ともにO(ΣPiEi)O(ΠPiEi)=O(M)O(ΣP_i ^ {E_i}) \leq O(ΠP_i ^ {E_i}) = O(M)です。
  • クエリではN,R,NRN,R,N-RPiP_i進数表記に変換し、その後連続したEiE_i桁ごとに二項係数の積を計算します。
    時間計算量は前者が各O(logPiN)O(log_{P_i} N)、後者は実装方針によりますがO(logPiN)O(log_{P_i} N)O(Ei×logPiN)O(E_i × log_{P_i} N)になります。
    ただしΣEilogMΣE_i \leq logMなので、どちらの実装であってもO(ΣEi×logPiN)O(logNlogM)O(ΣE_i × log_{P_i} N) \leq O(logNlogM)時間で抑えられます。
  • 中国剰余定理の復元はO(ΠlogPiEi)=O(logM)O(Πlog P_i ^ {E_i}) = O(logM)です。

なお本問の制約範囲外ですが、抽象化の際にはN,R=0N,R = 0N<RN < RM=1M = 1のケースに注意してください。

参考文献

一般化Lucasの定理と東大数学2021 - mathlog
https://mathlog.info/articles/1851

解答例(Python)

解答例では、二項係数が与えられるたびに階乗を計算しています。

一般化Lucasの定理 実装例(Python)

O(M+M)O(√M + M)時間・O(M)O(M)空間で階乗を前計算します。
二項係数クエリは1個あたりO(logNlogM)O(logNlogM)で計算します。

この実装例を用いた解答例を示します。