您的位置:首页 > 其它

【模板】卢卡斯定理

2017-10-25 20:31 204 查看

题目描述

给定n,m,p(1≤n,m,p≤1051\le n,m,p\le 10^51≤n,m,p≤105)

求 Cn+mm mod pC_{n+m}^{m}\ mod\ pCn+mm​ mod p

保证P为prime

C表示组合数。

一个测试点内包含多组数据。

输入输出格式

输入格式:

第一行一个整数T(T≤10T\le 10T≤10),表示数据组数

第二行开始共T行,每行三个数n m p,意义如上

输出格式:

共T行,每行一个整数表示答案。

输入输出样例

输入样例#1: 复制
2
1 2 5
2 1 5


输出样例#1: 复制
3
3


思路

卢卡斯定理;

C(m,n)%p=C(m/p,n/p)*C(m%p,n%p)%p;

代码

#include<cstdio>
const int maxn=1e5+10;
int T,n,m,p;
int f[maxn]={1};
void init(){for(int i=1;i<=p;i++) f[i]=(1ll*f[i-1]*i)%p;}
int FP(int x,int y){
int ret=1;
while(y){
if(y&1) ret=(1ll*ret*x)%p;
y>>=1,x=(1ll*x*x)%p;
}
return ret;
}
int IE(int x){return FP(x,p-2);}
int C(int m,int n){
if(m>n) return 0;
return 1ll*f
*IE(f[n-m])%p*IE(f[m])%p;
}
int Lucas(int m,int n){
if(!m) return 1;
return 1ll*Lucas(m/p,n/p)*C(m%p,n%p)%p;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&p);
init();
printf("%d\n",Lucas(m,n+m)%p);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: