卢卡斯定理学习笔记
III.Lucas(卢卡斯定理)
Lucas定理:
该式子仅适用于 为质数的情形。
证明:
首先,对于 ,有 ,这是显然的,因为展开式内必定包含 这一项。
于是,就有 。
我们设 ,其中 ,且都非零。则我们即要证 。
则必然有 。
现在,展开两个式子,得到 。
我们需要 这一项的系数,即为 。
(实际上关键就在于我们最上面证出的那个式子)
III.I.【模板】卢卡斯定理
代码:
#include<bits/stdc++.h>
using namespace std;
int T,n,m,mod,fac[100100],inv[100100];
int ksm(int x,int y=mod-2){
int z=1;
for(;y;y>>=1,x=1ll*x*x%mod)if(y&1)z=1ll*z*x%mod;
return z;
}
int C(int x,int y){
if(x<y)return 0;
if(x<mod&&y<mod)return 1ll*fac[x]*inv[y]%mod*inv[x-y]%mod;
return 1ll*C(x/mod,y/mod)*C(x%mod,y%mod)%mod;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&mod);
fac[0]=1;for(int i=1;i<mod;i++)fac[i]=1ll*fac[i-1]*i%mod;
inv[mod-1]=ksm(fac[mod-1]);for(int i=mod-2;i>=0;i--)inv[i]=1ll*inv[i+1]*(i+1)%mod;
printf("%d\n",C(n+m,n));
}
return 0;
}
III.II.[SHOI2015]超能粒子炮·改
设 。发现它是个质数。设 ,也即我们要求的东西。
因为 均很大,考虑直接往上套 Lucas。
除了 这一项以外,其它项的二维都在 以内,可以直接 预处理出来,而这项可以递归求解;然后那个二项式系数就直接常规Lucas处理掉即可。
时间复杂度 。
代码:
#include<bits/stdc++.h>
using namespace std;
const int P=2333;
typedef long long ll;
int C[2510][2510],S[2510][2510],T;
ll n,m;
int binom(ll x,ll y){if(x<y)return 0;if(x<P&&y<P)return C[x][y];return binom(x/P,y/P)*C[x%P][y%P]%P;}
int monib(ll x,ll y){if(y<0)return 0;if(x<P)return S[x][min(y,1ll*P-1)];return (S[x%P][P-1]*monib(x/P,y/P-1)+binom(x/P,y/P)*S[x%P][y%P])%P;}
int main(){
for(int i=0;i<P;i++)C[i][0]=C[i][i]=1;
for(int i=1;i<P;i++)for(int j=1;j<=i;j++)C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
for(int i=0;i<P;i++){S[i][0]=C[i][0];for(int j=1;j<P;j++)S[i][j]=(S[i][j-1]+C[i][j])%P;}
scanf("%d",&T);
while(T--)scanf("%lld%lld",&n,&m),printf("%d\n",monib(n,m));
return 0;
}
III.III.[SDOI2010]古代猪文
这题乍一看好像非常不可做,你模一个大质数求组合数,本身就是极为困难的,何况这题还在指数上……
等等,指数?
我们想起了著名的扩展欧拉定理:。在指数上,是要对 ,也就是 取模的!
,就是 。分解质因数,得到 。于是我们可以分别关于每个模数求值,最后CRT并一起即可。
我们要求 。我们可以直接枚举 ,然后用Lucas求组合数,复杂度 (据说因数个数可以按照 算)。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,g;
struct func{
int mod,fac[50100],inv[50100];
int ksm(int x,int y){
int z=1;
for(;y;y>>=1,x=1ll*x*x%mod)if(y&1)z=1ll*z*x%mod;
return z;
}
int C(int x,int y){
if(x<y)return 0;
if(x<mod&&y<mod)return 1ll*fac[x]*inv[y]%mod*inv[x-y]%mod;
return 1ll*C(x%mod,y%mod)*C(x/mod,y/mod)%mod;
}
int solve(){
fac[0]=1;for(int i=1;i<mod;i++)fac[i]=1ll*fac[i-1]*i%mod;
inv[mod-1]=ksm(fac[mod-1],mod-2);for(int i=mod-2;i>=0;i--)inv[i]=1ll*inv[i+1]*(i+1)%mod;
int ret=0;
for(int i=1;i*i<=n;i++){
if(n%i)continue;
(ret+=C(n,i))%=mod;
if(i*i!=n)(ret+=C(n,n/i))%=mod;
}
return ret;
}
}a[4];
const int mod=999911659;
const int phi=999911658;
int res;
int ksm(int x,int y,int mod){
int z=1;
for(;y;y>>=1,x=1ll*x*x%mod)if(y&1)z=1ll*z*x%mod;
return z;
}
int main(){
scanf("%d%d",&n,&g);
if(!(g%mod)){puts("0");return 0;}
a[0].mod=2,a[1].mod=3,a[2].mod=4679,a[3].mod=35617;
for(int i=0;i<4;i++)(res+=1ll*a[i].solve()*(phi/a[i].mod)%phi*ksm(phi/a[i].mod,a[i].mod-2,a[i].mod)%phi)%=phi;
printf("%d\n",ksm(g,res,mod));
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?