卢卡斯定理及其证明

结论#

CnmCn/pm/p×Cn mod pm mod p(mod p)

例题

Code
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define int long long

using namespace std;

int n,m,p,t,fac[105000];

int inv(int b,int q)//求逆元,费马小定理 
{
    int ans = 1;
    for(	;q;q >>= 1,b = b*b%p)
	{
        if( q%2 != 0 )
			ans = ans*b%p;
    }
    ans %= p;
    return ans;
}
int C(int n,int m)
{
    if( m > n )
		return 0;
    return fac[n]*inv((fac[m]*fac[n-m])%p,p-2)%p;
}
int Lucas(int n,int m)
{
    if( m == 0 )
		return 1;
    return (Lucas(n/p,m/p)*C(n%p,m%p))%p;
     
}
signed main()
{
    cin >> t;
    for(int i = 1;i <= t; i++)
	{
        cin >> n >> m >> p;
        fac[0] = 1;;
        for(int i = 1;i <= p; i++)//预处理阶乘 
		{
			fac[i] = fac[i-1]*i;
			fac[i] %= p;
		}
        printf("%lld\n",Lucas(n+m,m));
    }
    return 0;
}

证明#

引理一#

Cpx0 (mod p),0<x<p

证明:

Cpxp!x!(px)!p(p1)!x(x1)!(px)!pinv(x)Cp1x1 (mod p)

引理二#

(1+x)p1+xp (mod p)

证明:

二项式定理:

(a+b)n=r=0nCnranrbr

其中,等号右侧叫做等号左侧的二次展开式。

先进行二项式展开

(1+x)p=i=0pC(p,i)xi

根据引理一

i=0pC(p,i)xiC(p,0)x0++C(p,p)xp1+xp (mod p)

证明#

n=qnp+rn,m=qmp+rm

(1+x)n(1+x)qnp+rn(1+x)qnp(1+x)rn[(1+x)p]qn(1+x)rn(1+xp)qn(1+x)rni=0qnC(qn,i)xpij=0rnC(rn,j)xj (mod p)

又因为

(1+x)n=i=0nC(n,i)xi

所以

i=0nC(n,i)xii=0qnC(qn,i)xpij=0rnC(rn,j)xj (mod p)

取两边 xm 次项的系数,因为 m=qmp+rm,所以对于等式右边最多只有一种情况满足

CnmCn/pm/p×Cn mod pm mod p(mod p)

作者:白简

出处:https://www.cnblogs.com/baijian0212/p/lucas.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   -白简-  阅读(64)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu