[洛谷P3807]【模板】卢卡斯定理

题目大意:给你$n,m,p(p \in \rm prime)$,求出$C_{n + m}^m\bmod p(可能p\leqslant n,m)$

题解:卢卡斯$Lucas$定理,$C_B^A\bmod p$等于把$A,B$写成$p$进制时每一位的组合数相乘,设$A=a_n\times p^n+a_{n-1}\times p^{n-1}+\cdots+a_0$,$B=b_m\times p^m+b_{m-1}\times p^{m-1}+\cdots+b_0$,$C_B^A\bmod p=\prod\limits_{i=0}^{\min\{n,m\}}C_{b_i}^{a_i}$

卡点:

C++ Code:

#include <cstdio>
#define maxn 100010
int Tim, n, m, mod;
long long fac[maxn], inv[maxn];
inline long long CC(long long a, long long b) {
	if (a < b) return 0;
	return fac[a] * inv[b] % mod * inv[a - b] % mod;
}
inline long long C(long long a, long long b) {
	if (a < b) return 0;
	if (a <= mod) return CC(a, b);
	long long res = 1;
	while (a && b && res) {
		res = res * CC(a % mod, b % mod) % mod;
		a /= mod, b /= mod;
	}
	return res;
}
int main() {
	scanf("%d", &Tim);
	fac[0] = fac[1] = inv[0] = inv[1] = 1;
	while (Tim --> 0) {
		scanf("%d%d%d", &n, &m, &mod);
		for (long long i = 2; i <= mod; i++) fac[i] = fac[i - 1] * i % mod;
		for (int i = 2; i <= mod; i++) inv[i] = inv[mod % i] * (mod - mod / i) % mod;
		for (int i = 2; i <= mod; i++) inv[i] = inv[i] * inv[i - 1] % mod;
		printf("%lld\n", C(n + m, m));
	}
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/Memory-of-winter/p/9618810.html