luogu传送门 : Acwing传送门 :
思路首先给出卢卡斯定理 (就是将求 C ( a , b ) C(a,b) C(a,b)分而治之) C a b ≡ C a % p b % p ∗ l u c a s a p b p ( m o d p ) C_{a}^{b} \equiv C_{a \% p}^{b \% p} * lucas_{\frac{a}{p}}^{\frac{b}{p}}(\bmod p) Cab≡Ca%pb%p∗lucaspapb(modp)
显然的 : 我们左边 C C C是需要求的 而右边 l u c a s lucas lucas是通过递归求解 那么左边如何求呢 ? C a b = a ! ( a − b ) ! ∗ b ! = a ∗ ( a − 1 ) ∗ ( a − 2 ) ∗ … ∗ ( a − b + 1 ) ∗ ( a − b ) ∗ … ∗ 1 ( a − b ) ∗ ( a − b − 1 ) ∗ … ∗ 1 ∗ b ! = a ∗ ( a − 1 ) ∗ ( a − 2 ) ∗ … ( a − b + 1 ) b ! C_{a}^{b}=\frac{a !}{(a-b) ! * b !}=\frac{a *(a-1) *(a-2) * \ldots *(a-b+1) *(a-b) * \ldots * 1}{(a-b) *(a-b-1) * \ldots * 1 * b !}=\frac{a *(a-1) *(a-2) * \ldots(a-b+1)}{b !} Cab=(a−b)!∗b!a!=(a−b)∗(a−b−1)∗…∗1∗b!a∗(a−1)∗(a−2)∗…∗(a−b+1)∗(a−b)∗…∗1=b!a∗(a−1)∗(a−2)∗…(a−b+1)
我们通过化简可以发现,最后会化简成 每次 ∗ a 并 且 / b *a 并且 /b ∗a并且/b 因此,我们可以通过一层循环
直接求,同时因为需要牵扯到除法取模运算,我们还需要用快速幂求一次逆元
时间复杂度 O ( p + l o g p N ) O(p+log_pN) O(p+logpN)
遗留的问题 : 为什么右边不可以也用组合数求解,而是选择递归的求
CODEint qmi(int a, int k, int p)
{
int res = 1;
while (k)
{
if (k & 1) res = (LL)res * a % p;
a = (LL)a * a % p;
k >>= 1;
}
return res;
}
int C(int a, int b, int p)
{
if (b > a) return 0;
int res = 1;
for (int i = 1, j = a; i > a >> b >> p;
cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?