【模板】卢卡斯定理

tech2024-05-10  83

前往:我自己搭建的博客

题目

洛谷P3807卢卡斯定理

题解

若p是质数,则对于任意整数1<=m<=n:

如果要多次询问组合数的值,就需要预处理一些值。

注意用了Lucas定理后,可能出现C(0,0)的情况,令它为1。

代码

#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+5; ll n,m,p; ll s1[maxn],s2[maxn]; //s1[]表示阶乘,s2[]表示逆元前缀积 inline ll C(ll n,ll m) {return n<m ? 0 : s1[n]*s2[m]%p*s2[n-m]%p;} ll lucas(ll n,ll m) {return (n<=p&&m<=p) ? C(n,m) : lucas(n%p,m%p)*lucas(n/p,m/p)%p;} inline void pre() { s1[0]=s2[0]=s2[1]=1; //注意s2[0]=1很重要 for(ll i=1;i<=p;i++) s1[i]=(s1[i-1]*i)%p; for(ll i=2;i<=p;i++) s2[i]=(p-p/i)%p*s2[p%i]%p; for(int i=2;i<=p;i++) s2[i]=s2[i-1]*s2[i]%p; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%lld%lld%lld",&n,&m,&p); pre(); printf("%lld\n",lucas(n+m,n)); } return 0; }
最新回复(0)