Lucas 定理

发布时间 2023-08-12 23:03:41作者: ChElsYqwq

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

\[C_{n}^m\equiv C_{n/p}^{m/p}⋅C_{n\mod{p}}^{m\mod{p}} \]

或者说 \((n_i,m_i)\)\((n,m)\)\(p\) 进制上的一组,\(C_{n_i}^{m_i}\) 的积就是答案力(((

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 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(a<b) return 0;
	int res=1;
	for( ; a; a/=p, b/=p)
		res=res*c(a%p,b%p,p)%p;
	return res;
}

拓展 lucas

目前并没有学习。