拓展卢卡斯定理 / exlucas
恶心东西爬、、、
我们要求解一个
首先我们分解
问题是怎么求这个
然后求解
后面那一段其实是有一个长度为
写成递归的函数形式,那么
直接递归暴力做就行了谢谢喵,放回去原式,发现
然后终于他妈的做完了 /lh
#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
using namespace std;
int exgcd(int a,int b,int &x,int &y) {
if(!b) return y=0, x=1, a;
int ans=exgcd(b,a%b,y,x);
return y-=a/b*x, ans;
}
int inv(int a,int p) {
int x, y; exgcd(a,p,x,y);
return (x%p+p)%p;
}
int ksm(int a,int b,int p) {
int res=1%p;
for( ; b; b>>=1) {
if(b&1) res=res*a%p;
a=a*a%p;
}
return res;
}
int fac(int n,int pi,int pk) {
if(!n) return 1;
int res=1;
up(i,2,pk) if(i%pi) res=res*i%pk;
res=ksm(res,n/pk,pk);
up(i,2,n%pk) if(i%pi) res=res*i%pk;
return res*fac(n/pi,pi,pk)%pk;
}
int C(int n,int m,int pi,int pk) {
int above=fac(n,pi,pk), l=fac(m,pi,pk), r=fac(n-m,pi,pk), k=0;
for(int i=n; i; i/=pi) k+=i/pi;
for(int i=m; i; i/=pi) k-=i/pi;
for(int i=n-m; i; i/=pi) k-=i/pi;
return above*inv(l,pk)%pk*inv(r,pk)%pk*ksm(pi,k,pk)%pk;
}
int exlucas(int n,int m,int p) {
int ans=0, x=p, t=sqrt(x);
up(i,2,t) if(x%i==0) {
int mul=1;
while(x%i==0) x/=i, mul*=i;
ans=(ans+C(n,m,i,mul)*(p/mul)%p*inv(p/mul,mul)%p)%p;
}
if(x>1) ans=(ans+C(n,m,x,x)*(p/x)%p*inv(p/x,x)%p)%p;
return ans;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n, m, p;
cin >> n >> m >> p;
cout << exlucas(n,m,p);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】