明确一下,我们要求这个:
\[{n \choose m} \bmod t\]
defs
假设\(n,m,t \le 2^w\),\(w\)是字长,即认为+-×÷全是basic operation(\(O(1)\)).
\[{n \choose m} = \frac{n^{\underline{m}}}{m!} = \frac{n}{(m-n)!m!}\]
\[R_p(x)\]为\(x\)的质因数分解中质因数\(p\)的次数,若\(p\)不是质数则\(R_p(x)=0\).可以在\(O(\log_p{n})\)的时间复杂度内求出.
\[primes = \mathtt{Set~of~primes.}\]
\[pr(x) = [x \in primes]\]
algos
\(pr(t)~~t,n,m \le 10^9\)
预处理阶乘与阶乘逆元.
\(pr(t)~~t\le 10^9, n,m\le 10^{18}\)
Lucas定理.
\({n \choose m}\equiv {\lfloor n/t \rfloor \choose \lfloor m/t \rfloor} {n \bmod t \choose m \bmod t} \pmod{t}\)
\(O(n),O(\log{n})\)
Chinese remainder theorem(CRT)
解方程组\(\mathtt{Constraint:~}\forall i\not= j,\gcd{i,j}=1,\mathtt{Equations:~}\forall i,x\equiv y_i\pmod{t_i}\)
(有点显然,但是需要证明)\(x\equiv \sum_i y_i b_i \frac{\prod_j t_j}{t_i} \pmod{\prod_j t_j}\),其中\(b_i=\left(\left( \prod_j t_j \right) / t_i\right)^{-1} \bmod t_i\),大概考虑下贡献什么的就能理解它的正确性.
\(pr(t)~~t\le 10^{10}, n,m\le 10^{18}\)
前置技能FFT mod any prime,多项式多点求值.(而且数据范围略鬼畜,好自为之吧(如果你要去写的话= =))
考虑如何求出阶乘,构造多项式\(f_n(x)=\prod_{i=1}^n(x+i)\),显然\(n!=f_n(0)\).我们考虑如何计算.那么我们考虑\(f_n(0)=\prod_{i=0}^mf_m(im)\)(其中\(n\)=\(m^2\)),如果不是\(n\)完全平方数只会剩下\(O(\sqrt{n})\)项,暴力做,不然就先把这个式子求出来,多点求值一下.复杂度是\(O(\sqrt{n}\log^2{n})\),当然做\(n,m\le 10^{18}\)就顺手Lucas一发(求两次).如果你有工业级的工具可以去试试.
\(t=p^q, pr(p)\)
\(q=1\)用上面的算法,否则\(p\)不太大.
首先用\(R\)函数处理掉答案的\(p\)因子,现在问题是求\(f_n\bmod{p^q}\).我们发现这时的\(f_n\)最高次项最多是\(q-1\)次(显然).考虑倍增\(f_n\).
\(f_{2px+d}=f_{px}f_{px}(px)f_d(2px)\).其中\(d\le p\),那么复杂度是\(O(q^2)\)倍增一次,总共\(O(\log{n})\)次,加上预处理\(f_d\)总复杂度\(O(q^2\log{n}+pq)\).
这里计算都是纯暴力计算.大约可以优化一下但是因为p不会很大应该也只有优化\(f_d\)的计算会有些实际意义.
没有性质的题目
CRT+上面的算法+一些优化.
常数优化
然而我们的\(f_n\)函数可以直接求下降幂,常数/1.5 get.
为什么\(O(n)\)能跑\(10^9\)
假设是题答/PE环境.