(exlucas)
用于计算任意模数的组合数。
一般情况下我们要求的是:
[inom{n}{m} mod P,n<1e9,m<1e9
]
我们设:(P=\_*p^k,p^k<1e5)
注意到由于各个质因子之间互质而且(p^k)很小。
那么我们可以利用(CRT)来处理这种情况,直接计算:
[inom{n}{m} mod p^k
]
怎么做呢?
首先我们不能直接用(lucas)算这个组合数的原因是(p^k)不是质数。
其次我们不能直接暴力来计算这个组合数的原因是(n,m)数据范围过大。
再退一步讲,由于分子分母上下可以消去(p)的次幂,我们可能会将本来互质的部分模为0。
由于存在一种(log_p)求阶乘中含有某个数的次幂的方法。
也就是说需要计算互质的部分了,因为这部分存在逆元,剩下含有(p)的部分直接(log_p)处理出来即可。
我们实际上需要求得就是:
[prodlimits_{i=1,iperp p}^{n}i
]
我们发现:
[prodlimits_{i=1,iperp p}^{p^k-1}equivprodlimits_{i=1perp p}^{p^k-1}(i+tp^k) mod p^k
]
那么这样的话存在的
[prodlimits_{i=1,iperp p}^{p^k-1}
]
就只有(lfloorfrac{n}{p^k}
floor)段
直接快速幂乘起来就可以了。
剩下的(n mod p^k)的那一部分小于(p^k)可以直接预处理出来(如果只求求一个组合数就暴力算就可以)。
然后整理出除去(p)的部分剩下的互质部分的乘积,发现这是另外一个阶乘(lfloorfrac{n}{p}
floor!)直接递归处理即可。
这样的话就得到了互质部分的阶乘。
直接乘起来或者求逆元并顺手计算出含(p)的部分即可。