Lucas 定理

lucas 定理用于求解模数很的组合数求解,比如模小素数,会遇到不一定互质即没有逆元的情况。

CnmCn/pm/pCnmodpmmodp

或者说 (ni,mi)(n,m)p 进制上的一组,Cnimi 的积就是答案力(((


因为你可能想问为什么,所以原神会告诉你答案。

我们要求解 Cnmmodp,我们设 n=ap+b,m=cp+d,其中 0b,d<p

我们要证明的是 Cnm=CabCcd(modp)

根据二项式定理,Cnm(1+x)nxm 的系数是相等的。

我们在 modp 意义下进行推导:

(1+x)n(1+x)ap+b((1+x)p)a(1+x)b

对于 Cpi=p!i!(pi)!,只有当 i=0,p 的时候取到 1,其它时候都是 p 的倍数。 我们把 (1+x)p 展开,在 modp 的情况下其实只剩下 1+xp 了,继续推导 qwq

((1+x)p)a(1+x)b(1+xp)a(1+x)bi=0aCaixpij=0bCbjxj

我们再次回看 xm 的系数,你不是 m=cp+d 嘛,那是不是等于 CacCbd,赢!

int p, mul[MN], inv[MN]; 
mul[0]=inv[0]=1;
mul[1]=inv[1]=1;
for(int i=2; i<p; ++i) mul[i]=mul[i-1]*i%p;
for(int i=2; i<p; ++i) inv[i]=inv[p%i]*(p-p/i)%p;
for(int i=2; i<p; ++i) inv[i]=inv[i-1]*inv[i]%p;
int c(int a,int b,int p) {
	if(a<b) return 0;
	return (mul[a]*inv[b]%p)*inv[a-b]%p;
}
int lucas(int a,int b,int p) {
	if(b==0) return 1;
	int lucas(a/p,b/p,p)*c(a%p,b%p,p)%p;
}

不想递归的话,可以这么写 qwq

int lucas(int a,int b,int p) {
	if(a<b) return 0;
	int res=1;
	for( ; a; a/=p, b/=p)
		res=res*c(a%p,b%p,p)%p;
	return res;
}
posted @   Hypoxia571  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示