解説
各素因数ごとに 一般化Lucasの定理 で(RN) mod PiEiを計算し、中国剰余定理で解を復元します。
一般化Lucasの定理の詳細は参考文献をご覧ください。
計算量は前計算O(M)時間・空間、クエリO(logNlogM+logM)時間になります。
内訳は以下の通りです。
- 前計算では、Piの倍数を除いた階乗x!Pi mod PiEiをPiEiまで計算すればよいです。
計算量は時間・空間ともにO(ΣPiEi)≤O(ΠPiEi)=O(M)です。
- クエリではN,R,N−RをPi進数表記に変換し、その後連続したEi桁ごとに二項係数の積を計算します。
時間計算量は前者が各O(logPiN)、後者は実装方針によりますがO(logPiN)やO(Ei×logPiN)になります。
ただしΣEi≤logMなので、どちらの実装であってもO(ΣEi×logPiN)≤O(logNlogM)時間で抑えられます。
- 中国剰余定理の復元はO(ΠlogPiEi)=O(logM)です。
なお本問の制約範囲外ですが、抽象化の際にはN,R=0やN<R、M=1のケースに注意してください。
参考文献
一般化Lucasの定理と東大数学2021 - mathlog
https://mathlog.info/articles/1851
解答例(Python)
解答例では、二項係数が与えられるたびに階乗を計算しています。
一般化Lucasの定理 実装例(Python)
O(√M+M)時間・O(M)空間で階乗を前計算します。
二項係数クエリは1個あたりO(logNlogM)で計算します。
この実装例を用いた解答例を示します。