您的位置:首页 > 其它

组合数取模(卢卡斯定理、模板)

2016-05-24 14:42 393 查看
卢卡斯定理:

用来求C(n,m)%p。p要求为素数,且不能太大。

复杂度为O(logp(n)*p)。

代码:

#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<cstdlib>
#include<vector>
#define C    240
#define TIME 10
#define LL  __int64
using namespace std;
LL PowMod(LL a,LL b,LL MOD){
LL ret=1;
while(b){
if(b&1) ret=(ret*a)%MOD;
a=(a*a)%MOD;
b>>=1;
}
return ret;
}
LL fac[100005];
LL Get_Fact(LL p){
fac[0]=1;
for(LL i=1;i<=p;i++)
fac[i]=(fac[i-1]*i)%p;  //预处理阶乘
}
LL Lucas(LL n,LL m,LL p){
LL ret=1;
while(n&&m){
LL a=n%p,b=m%p;
if(a<b) return 0;
ret=(ret*fac[a]*PowMod(fac[b]*fac[a-b]%p,p-2,p))%p;
n/=p;
m/=p;
}
return ret;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
LL n,m,p;
scanf("%I64d%I64d%I64d",&n,&m,&p);
Get_Fact(p);

printf("%I64d\n",Lucas(n,m,p));
}
return 0;
}
/*
卢卡斯定理
O(logp(n)*p)
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: