关于lucas定理的那些事儿

about 组合数

我们知道, C n m C_n^m Cnm表示表示从 n 个元素中取出 m 个元素的方案数,在做数学题时,题目一般不会将n和m给到太大的数。所以我们一般会用以下公式:

C n m = n ! m ! × ( n − m ) ! C_n^m=\frac{n!}{m! \times (n-m)!} Cnm=m!×(nm)!n!

在编程时,我们还会使用杨辉三角公式:

杨辉三角公式求组合数
或者质因数分解求组合数:

我们需要计算 n!(n 的阶乘),即 n! = n × (n-1) × (n-2) ×… × 1。为了提高计算效率,我们可以利用质因数分解的方法将 n! 分解成若干个质数的乘积,如下所示:

n ! = p 1 a 1 × p 2 a 2 × . . . × p k a k n! = p1^a1 × p2^a2 ×... × pk^ak n!=p1a1×p2a2×...×pkak

其中 p1, p2,…, pk 是 n 的质因数,a1, a2,…, ak 是相应质因数的指数。

接下来,我们将组合数计算公式 C n m C_{n}^{m} Cnm 改写为:

C n m = n ! m ! ( n − m ) ! C_{n}^{m} = \frac{n!}{m!(n-m)!} Cnm=m!(nm)!n!

利用 n! 的质因数分解形式,可以将上式改写为:

C n m = p 1 a 1 × p 2 a 2 × . . . × p k a k m ! ( n − m ) ! C_{n}^{m} = \frac{p1^a1 × p2^a2 ×... × pk^ak}{m!(n-m)!} Cnm=m!(nm)!p1a1×p2a2×...×pkak

为了方便计算,我们可以将分母的 m! 和 (n-m)! 分别表示为质因数分解的形式:

m ! = p 1 b 1 × p 2 b 2 × . . . × p x b x m! = p1^{b1} × p2^{b2} ×... × px^{bx} m!=p1b1×p2b2×...×pxbx

( n − m ) ! = q 1 c 1 × q 2 c 2 × . . . × q y c y (n-m)! = q1^{c1} × q2^{c2} ×... × qy^{cy} (nm)!=q1c1×q2c2×...×qycy

其中 p1, p2,…, px 是 m 的质因数,b1, b2,…, bx 是相应
质因数的指数;q1, q2,…, qy 是 n-m 的质因数,c1,

c2,…, cy 是相应质因数的指数。

将分母的质因数分解形式代入组合数公式,得到:

C n m = p 1 a 1 × p 2 a 2 × . . . × p k a k p 1 b 1 × p 2 b 2 × . . . × p x b x × q 1 c 1 × q 2 c 2 × . . . × q y c y C_{n}^{m} = \frac{p1^a1 × p2^a2 ×... × pkak}{p1b1 × p2^b2 ×... × px^bx × q1^c1 × q2^c2 ×... × qy^cy} Cnm=p1b1×p2b2×...×pxbx×q1c1×q2c2×...×qycyp1a1×p2a2×...×pkak

接下来,我们可以约分分子和分母中的公共质因数,以得到组合数 C_{n}^{m} 的最简形式。

好了,我们已经介绍了求组合数的三种基本做法,现在你可以尝试拿到这一题的部分分了。

lucas 定理

很明显,这一题的数据有点大,如果用第一,三种,会TLE,用第二种,会MLE。

就像题目说的:

P3807 【模板】卢卡斯定理/Lucas 定理

我们知道,要用新算法了。

lucas 定理概念

lucas定理用来求 C n m m o d    p C_n^m \mod p Cnmmodp的值,其中p为素数。

lucas定理的公式为:

l u c a s n m = C n m m o d    p = C n m o d    p m m o d    p × l u c a s [ n p ] [ m p ] m o d    p lucas_n^m=C_n^m\mod p=C_{n\mod p}^{m\mod p}\times lucas_{[\frac{n}{p}]}^{[\frac{m}{p}]}\mod p lucasnm=Cnmmodp=Cnmodpmmodp×lucas[pn][pm]modp

证明:

引理1

C p x ≡ 0 ( m o d p ) C_p^x \equiv 0 \pmod p Cpx0(modp)

引理1证明

根据 C n m = n ! m ! × ( n − m ) ! C_n^m=\frac{n!}{m!\times (n-m)!} Cnm=m!×(nm)!n!,得:
C p x = p ! x ! × ( x − p ) ! C_p^x=\frac{p!}{x!\times (x-p)!} Cpx=x!×(xp)!p!
∴ C p x = p × ( p − 1 ) ! x × ( x − 1 ) ! × ( p − x ) ! \therefore C_p^x =\frac{p\times (p-1)!}{x\times (x-1)!\times (p-x)!} Cpx=x×(x1)!×(px)!p×(p1)!

∴ C p x = p x × ( p − 1 ) ! ( x − 1 ) ! × ( p − x ) ! = p x × C p − 1 x − 1 \therefore C_p^x =\frac{p}{x}\times \frac{(p-1)!}{(x-1)!\times (p-x)!}=\frac{p}{x}\times C_{p-1}^{x-1} Cpx=xp×(x1)!×(px)!(p1)!=xp×Cp1x1

∴ C p x = p × i n v ( x ) × C p − 1 x − 1 \therefore C_p^x = p\times inv(x) \times C_{p-1}^{x-1} Cpx=p×inv(x)×Cp1x1
(inv(x)为x的逆元)
∴ p ∣ C p x \therefore p|C_p^x pCpx

∴ 证毕 \therefore 证毕 证毕

引理2

( 1 + x ) p ≡ 1 + x p ( m o d p ) (1+x)^p \equiv 1+x^p \pmod p (1+x)p1+xp(modp)

引理2证明

我们知道:

∴ ( 1 + x ) p = 1 p + 1 p − 1 × x + 1 p − 2 × x 2 + . . . + x p \therefore (1+x)^p=1^p+1^{p-1}\times x+1^{p-2}\times x^2+...+x^p (1+x)p=1p+1p1×x+1p2×x2+...+xp

= C p 0 × 1 p + C p 1 × 1 p − 1 × x + . . . + C p p × x =C_p^0\times 1^p + C_p^1 \times 1^{p-1}\times x +...+C_p^p\times x =Cp0×1p+Cp1×1p1×x+...+Cpp×x

化简,得:

( 1 + x ) p = ∑ i = 0 p C p i × x i (1+x)^p=\sum_{i=0}^p C_p^i \times x^i (1+x)p=i=0pCpi×xi

由引理1得 C p i × x i ≡ 0 ( m o d p ) ( i ≠ 0 , i ≠ p ) C_p^i \times x^i \equiv 0 \pmod p (i≠0,i≠p) Cpi×xi0(modp)(i=0,i=p)

C p 0 × x 0 × 1 p = 1 C_p^0 \times x^0 \times 1^p = 1 Cp0×x0×1p=1
C p p × x p × 1 0 = x p C_p^p \times x^p \times 1^0 = x^p Cpp×xp×10=xp
∴ C p i × x i m o d    p = ( C p 0 × x 0 × 1 p + C p p × x p × 1 0 ) = 1 + x p ( m o d p ) \therefore C_p^i \times x^i \mod p = (C_p^0 \times x^0 \times 1^p + C_p^p \times x^p \times 1^0) = 1+x^p \pmod p Cpi×ximodp=(Cp0×x0×1p+Cpp×xp×10)=1+xp(modp)

∴ 得证 \therefore 得证 得证

lucas定理证明

令n=ap+b,m=cp+d

( 1 + x ) n ≡ ∑ i = 0 n C n i × x i ( m o d p ) − − − − > 记为 ( 1 ) (1+x)^n\equiv \sum_{i=0}^{n} C_n^i \times x^i \pmod p ---->记为(1) (1+x)ni=0nCni×xi(modp)>记为(1)
≡ ( 1 + x ) a p + b \equiv(1+x)^{ap+b} (1+x)ap+b
≡ ( ( 1 + x ) p ) a × ( 1 + x ) b \equiv((1+x)^p)^a\times (1+x)b ((1+x)p)a×(1+x)b
结合引理2得:
≡ ( 1 + x p ) a + ( 1 + x ) b \equiv(1+x^p)^a+(1+x)^b (1+xp)a+(1+x)b
≡ ∑ i = 0 a C a i × x i p × ∑ i = 0 b C b j × x j ( m o d p ) − − > 记为 ( 2 ) \equiv\sum_{i=0}^{a}C_a^i\times x^{ip}\times\sum_{i=0}^{b}C_b^j\times x^j \pmod p-->记为(2) i=0aCai×xip×i=0bCbj×xj(modp)>记为(2)

(1)中 x m x^m xm的系数为 C n i = m = C n m C_n^{i=m} = C_n^m Cni=m=Cnm

(2)中 x m x^m xm的系数为 C a c × C b d C_a^c\times C_b^d Cac×Cbd

∴ C n m ≡ C a c × C b d ( m o d p ) \therefore C_n^m \equiv C_a^c\times C_b^d \pmod p CnmCac×Cbd(modp)
∴ C n m ≡ C n m o d    p m m o d    p × C [ n p ] [ m p ] ≡ C n m o d    p m m o d    p × l u c a s [ n p ] [ m p ] ( m o d p ) \therefore C_n^m\equiv C_{n\mod p}^{m\mod p}\times C_{[\frac{n}{p}]}^{[\frac{m}{p}]} \equiv C_{n\mod p}^{m\mod p}\times lucas_{[\frac{n}{p}]}^{[\frac{m}{p}]}\pmod p CnmCnmodpmmodp×C[pn][pm]Cnmodpmmodp×lucas[pn][pm](modp)

∴ 得证 \therefore 得证 得证

about题目

知道了lucas的公式,求解这道题就很简单了吧。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,m,p;
int ksm(int a,int b,int p){//a^b mod p
	int res=1;
	while(b){
		if(b&1)res=res*a%p;
		a=a*a%p;
		b>>=1;
	}
	return res;
}
int C(int n,int m,int p){
	if(n<m)return 0;
	if(m>n-m)m=n-m;//for example, C(3,2)=C(3,1) 
	//C(n,m) mod p = n! * (m! * (n-m)!)^(p-2)  mod p
	//             = n! / (n-m)! * (m!)^(p-2) mod p
	int r1=1,r2=1;
	for(int i=0;i<m;i++){
		r1=r1*(n-i)%p;
		r2=r2*(i+1)%p;
	}
	return r1*ksm(r2,p-2,p)%p;
}
int lucas(int n,int m,int p){
	//lucas(n,m)=c(n,m) mod p = C(n%p,m%p) * lucas(n/p,m/p)
	if(m==0)return 1;
	return C(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
}
signed main(){
	cin>>t;
	for(int i=1;i<=t;i++){
		cin>>n>>m>>p;
		m=n+m;
		cout<<lucas(m,n,p)<<endl;
	}
	return 0;
}

其中,ksm(r2,p-2,p)是求r2的逆元。

码字不易,点下一个赞吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值