题目大意:求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; }
时间: 2024-10-18 04:41:54