题目大意:求C(n,m)%p。
思路:Lucas定理:C(n,m)%p = C(n/p,m/p)*C(n%p,m%p)%p
处理出来1~10007所有的阶乘和阶乘的逆元,nm都小于10007的时候就可以直接算了,剩下的情况递归处理。
CODE:
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 11000
#define p 10007
using namespace std;
int inv[MAX],fac[MAX];
void Shaker()
{
inv[1] = 1;
for(int i = 2; i < MAX; ++i)
inv[i] = (p - p / i) * inv[p % i] % p;
fac[0] = 1;
for(int i = 1; i < MAX; ++i)
fac[i] = fac[i - 1] * i % p;
inv[0] = 1;
for(int i = 1; i < MAX; ++i)
inv[i] = inv[i - 1] * inv[i] % p;
}
int C(int n,int m)
{
if(n < m) return 0;
if(n < p && m < p)
return fac[n] * inv[m] % p * inv[n - m] % p;
return C(n / p,m / p) * C(n % p,m % p) % p;
}
int x,y,cases;
int main()
{
Shaker();
for(cin >> cases; cases--;) {
scanf("%d%d",&x,&y);
printf("%d\n",C(x,y));
}
return 0;
}