Link:http://acm.fzu.edu.cn/problem.php?pid=2020
Problem 2020 组合
Accept: 776 Submit: 1849
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
给出组合数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
25 2 35 2 61
Sample Output
110
Source
FOJ有奖月赛-2011年04月(校赛热身赛)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#define LL long long
#define MAXN 1000010
using namespace std;
const int N=20;//模方程数
LL a[N],mod[N];
/*LL mul(LL a,LL b,LL mod)//a*b%mod
{
LL ans=0;
while(b){
if(b&1)
ans=(ans+a)%mod;
b>>=1;
a=(a+a)%mod;
}
return ans;
}
*/
LL quick_mod(LL a,LL b,LL m)//a^b%m
{
LL ans=1;
a%=m;
while(b)
{
if(b&1)
{
ans=ans*a%m;
}
b>>=1;
a=a*a%m;
}
return ans;
}
LL getC(LL n,LL m,int cur)//C(n,m)%mod[cur]
{
LL p=mod[cur];
if(m>n)
return 0;
if(m>n-m)
m=n-m;
LL ans=1;
for(int i=1;i<=m;i++)
{
LL a=(n+i-m)%p;
LL b=i%p;
//ans=mul(ans,mul(a,quick_mod(b,p-2,p),p),p);//p为素数,i对p的逆元可以不用扩张欧几里得进行求解 re=i^(P-2)
//ans=(ans*(a*quick_mod(b,p-2,p))%p)%p;
ans = ans * (a * quick_mod(b, p-2,p) % p) % p;
}
return ans;
}
LL Lucas(LL n,LL k,int cur)//求C(n,k)%mod[cur]
{
LL p=mod[cur];
if(k==0)
return 1%p;
//return getC(n%p,k%p,cur)*Lucas(n/p,k/p,cur)%p;
return getC(n % p, k % p,cur) * Lucas(n / p, k / p,cur) % p;
}
/*void extend_Euclid(LL a,LL b,LL &x,LL &y)
{
if(b==0)
{
x=1;
y=0;
return;
}
extend_Euclid(b,a%b,x,y);
LL tmp=x;
x=y;
y=tmp-a/b*y;
}
LL CRT(LL a[],LL m[],int k)//求C(n,m)%M,其中M=(m0*m2*…*m(k-1)),mi为素数,则先用a[i]存储模方程C(n,m)%mi,
{ //m[]存储所有素数因子mi,k表示总共有k个模方程,返回C(n,m)%M的值
LL M=1;
LL ans=0;
for(int i=0;i<k;i++)
M*=mod[i];
for(int i=0;i<k;i++)
{
LL x,y,tmp;
LL Mi=M/m[i];
extend_Euclid(Mi,m[i],x,y);
if(x<0)
{
x=-x;
tmp=mul(Mi,x,M);
tmp=mul(tmp,a[i],M);
tmp=-tmp;
}
else
{
tmp=mul(Mi,x,M);
tmp=mul(tmp,a[i],M);
}
ans=(ans+tmp)%M;
}
while(ans<0)
ans+=M;
return ans;
}*/
int main()
{
//freopen("D:\\in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
LL n,m;
int k;
scanf("%lld%lld",&n,&m);
k=1;
for(int i=0;i<k;i++)
scanf("%lld",&mod[i]);
for(int i=0;i<k;i++)
a[i]=Lucas(n,m,i)%mod[i];
printf("%I64d\n",a[0]);
}
return 0;
}