题目链接:
http://acm-hit.sunner.cn/judge/show.php?Proid=2813
题目大意:
给你三个整数 N、M、P,求组合数 C(N+M-2,M-1) % P。
解题思路:
将阶乘表示为大整数分解的形式,将各个素因子按素因子的幂相乘起来就是所求
答案(记得要对 P 取余)。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;
const int MAXN = 200000;
bool Prime[MAXN+10];
int Primer[MAXN+10];
int GetPrime()
{
for(int i = 2; i <= MAXN; ++i)
Prime[i] = true;
for(int i = 2; i <= MAXN; ++i)
{
if(Prime[i])
for(int j = i+i; j <= MAXN; j+=i)
Prime[j] = false;
}
int num = 0;
for(int i = 2; i <= MAXN; ++i)
if(Prime[i])
Primer[num++] = i;
return num;
}
int PowMod(LL a,LL b,LL mo)
{
LL ret = 1;
while(b)
{
if(b & 1)
ret = ret * a % mo;
a = a * a % mo;
b >>= 1;
}
return ret;
}
int Cal(int n,int p)
{
int sum = 0;
while(n)
{
n /= p;
sum += n;
}
return sum;
}
int main()
{
int T,N,M,Mod;
int num = GetPrime();
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&N,&M,&Mod);
N += M-2;
M--;
LL ans = 1;
for(int i = 0; i < num && Primer[i] <= N; ++i)
{
int temp = Cal(N,Primer[i]) - Cal(M,Primer[i]) - Cal(N-M,Primer[i]);
ans = ans * PowMod(Primer[i],temp,Mod) % Mod;
}
printf("%lld\n",ans);
}
return 0;
}