任重而道远
题目描述
给定n,m,p( 1\le n,m,p\le 10^51≤n,m,p≤105 )
求 C_{n+m}^{m}\ mod\ pCn+mm mod p
保证P为prime
C表示组合数。
一个测试点内包含多组数据。
输入输出格式
输入格式:第一行一个整数T( T\le 10T≤10 ),表示数据组数
第二行开始共T行,每行三个数n m p,意义如上
共T行,每行一个整数表示答案。
AC代码:#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 150000;
ll fac[N], m, n;
int T, p;
ll read () {
ll x = 0, jud = 1;
char c = getchar ();
while (c < '0' || c > '9') {
if (c == '-') jud = -1;
c = getchar ();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar ();
}
return x * jud;
}
void init () {
fac[0] = 1;
for (int i = 1; i <= p; i++)
fac[i] = fac[i - 1] * i % p;
}
void exgcd ( ll a, ll b, ll& cd, ll& x, ll& y ) {
if (b == 0) {
x = 1; y = 0;
cd = a;
} else {
exgcd (b, a % b, cd, y, x);
y -= x * (a / b);
}
}
ll C ( ll n, ll m ) {
if (m > n) return 0;
ll x, y, cd;
exgcd (fac[m] * fac[n - m], p, cd, x, y);
x = (x % p + p) % p;
return fac[n] * x % p;
}
ll Lucas ( ll n, ll m ) {
if (m == 0)
return 1;
return C (n % p, m % p) * Lucas (n / p, m / p) % p;
}
int main () {
scanf ("%d", &T);
while (T--) {
n = read (); m = read ();
scanf ("%d", &p);
init ();
printf ("%lld\n", Lucas (n + m, m));
}
}