明确一下,我们要求这个:
defs
假设(n,m,t le 2^w),(w)是字长,即认为+-×÷全是basic operation((O(1))).
algos
(pr(t)~~t,n,m le 10^9)
预处理阶乘与阶乘逆元.
(pr(t)~~tle 10^9, n,mle 10^{18})
Lucas定理.
({n choose m}equiv {lfloor n/t floor choose lfloor m/t floor} {n mod t choose m mod t} pmod{t})
(O(n),O(log{n}))
Chinese remainder theorem(CRT)
解方程组(mathtt{Constraint:~}forall i ot= j,gcd{i,j}=1,mathtt{Equations:~}forall i,xequiv y_ipmod{t_i})
(有点显然,但是需要证明)(xequiv 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 ight) / t_i ight)^{-1} mod t_i),大概考虑下贡献什么的就能理解它的正确性.
(pr(t)~~tle 10^{10}, n,mle 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,mle 10^{18})就顺手Lucas一发(求两次).如果你有工业级的工具可以去试试.
(t=p^q, pr(p))
(q=1)用上面的算法,否则(p)不太大.
首先用(R)函数处理掉答案的(p)因子,现在问题是求(f_nmod{p^q}).我们发现这时的(f_n)最高次项最多是(q-1)次(显然).考虑倍增(f_n).
(f_{2px+d}=f_{px}f_{px}(px)f_d(2px)).其中(dle p),那么复杂度是(O(q^2))倍增一次,总共(O(log{n}))次,加上预处理(f_d)总复杂度(O(q^2log{n}+pq)).
这里计算都是纯暴力计算.大约可以优化一下但是因为p不会很大应该也只有优化(f_d)的计算会有些实际意义.
没有性质的题目
CRT+上面的算法+一些优化.
常数优化
然而我们的(f_n)函数可以直接求下降幂,常数/1.5 get.
为什么(O(n))能跑(10^9)
假设是题答/PE环境.