Lucas定理以及证明
对着无数篇博客终于\(yy\)懂了\(Lucas\)定理,兴奋之际赶紧写下来
内容
如果\(p\)是质数,那么\(C_{n}^{m}\equiv C_{n\mod p}^{m\mod p}\times C_{n/p}^{m/p}(mod\ p)\)
证明
首先我们要知道一个性质:
如果\(p\)为质数,那么有\(C_{p}^{n}\equiv 0(mod\ p)\),其中\(n\ne 0,p\)
这个很显然吧,考虑把组合数的式子写出来:\(C_p^n=\frac{p!}{n!(p-n)!}\)
把\(p\)提出来就变成了\(\frac{(p-1)!}{n!(p-n)!}\times p\),就证完了
这个性质有什么用呢?别着急,我们先往下走
由二项式定理得:\((x+1)^p=\sum _{i=0}^{p}C_p^i\times x^i\)
而根据上面的性质,因为\(n\)只有在等于\(0\)或\(p\)时才为\(1\),其余时都为\(0\)得到在模\(p\)意义下
设\(n=\left \lfloor \frac{n}{p} \right \rfloor\times p+n\ mod \ p\)
那么可得\((x+1)^n\equiv (x+1)^{\left \lfloor \frac{n}{p} \right \rfloor\times p}+(x+1)^{n\ mod\ p}(mod\ p)\)
替换得\((x+1)^n\equiv (x^p+1)^{\left \lfloor \frac{n}{p} \right \rfloor}+(x+1)^{n\ mod\ p}(mod\ p)\)
根据二项式定理,展开得
观察这个式子,我们发现对于每一个\(i\),都一定存在\(j,k\)与其对应,保证\(x^i=x^j\times x^k\),约掉之后就是\(Lucas\)了
证毕
代码很好写,丢下板子题代码QAQ
#include <iostream>
#include <cstdio>
#define int long long
using namespace std;
int t,m,n,p;
int mypow(int a,int x)
{
int s=1;
while (x)
{
if (x&1)s=s*a%p;
a=a*a%p;
x>>=1;
}
return s;
}
int C(int m,int n)
{
if (m>n)return 0;
int a=1,b=1;
for (int i=1;i<=n;i++)a=a*i%p;
for (int i=1;i<=m;i++)b=b*i%p;
for (int i=1;i<=n-m;i++)b=b*i%p;
return a*mypow(b,p-2)%p;
}
int lucas(int m,int n)
{
if (!m)return 1;
return C(m%p,n%p)*lucas(m/p,n/p)%p;
}
signed main()
{
cin>>t;
while (t--)
{
cin>>n>>m>>p;
cout<<lucas(m,m+n)<<endl;
}
return 0;
}
扩展\(Lucas\)感觉实际用途比较少,而且复杂度可能不太对,就不放了
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步