组合数取模

明确一下,我们要求这个:

[{n choose m} mod 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)~~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环境.

原文地址:https://www.cnblogs.com/tmzbot/p/5675004.html