给出组合数C(n,m), 表示从n个元素中选出m个元素的方案数。例如C(5,2) = 10, C(4,2) = 6.可是当n,m比较大的时候,C(n,m)很大!于是xiaobo希望你输出 C(n,m) mod p的值!
Input
输入数据第一行是一个正整数T,表示数据组数 (T <= 100) 接下来是T组数据,每组数据有3个正整数 n, m, p (1 <= m <= n <= 10^9, m <= 10^4, m < p < 10^9, p是素数)
Output
对于每组数据,输出一个正整数,表示C(n,m) mod p的结果。
Sample Input
2
5 2 3
5 2 61
Sample Output
1
10
扩展欧几里得求逆元的板子题
#include<iostream>
using namespace std;
typedef long long LL;
LL mod;
LL exgcd(LL a,LL b,LL &x,LL &y) //扩展欧几里得
{
if(b==0)
{
x=1;
y=0;
return a;
}
LL res=exgcd(b,a%b,y,x);
y-=a/b*x;
return res;
}
LL Inv(LL a) //求逆元
{
LL d,x,y;
d=exgcd(a,mod,x,y);
if(d==1)
return (x%mod+mod)%mod;
return -1;
}
LL C(LL n,LL m) //组合
{
LL ans1=1,ans2=1,i=n,j=1;
for(;j<=m;j++,i--)
{
ans1=ans1*i%mod;
ans2=ans2*j%mod;
}
LL ans=ans1*Inv(ans2)%mod;
return ans;
}
int main()
{
int t;
LL n,m;
cin>>t;
while(t--)
{
cin>>n>>m>>mod;
cout<<C(n,m)<<endl;
}
return 0;
}