jQuery火箭图标返回顶部代码 - 站长素材
jQuery火箭图标返回顶部代码 - 站长素材

关于卢卡斯定理

关于卢卡斯定理Lucas

学习博客有点巧,学长在写这篇博客的时候机房在装修现在我在写机房也在装修233

感谢\(lfd\)

内容:

\(C_n^m \% p=(C_{n/p}^{m/p}\%p)*(C_{n\%p}^{m\%p})\%p\)

做题什么的一般就用这个的
证明:

\(peach\)我还会证明\(?\)
会公式就好了,要说多少遍才能记住?
信息学奥赛并不需要证明!

应用:

求大组合数\(\color{green}{取模}\)的情况
模数取值范围适中就是不大不小
这时\(C_n^m=C_{n-1}^{m}+C_{n-1}^{m-1}\)便不再适用
来一道例题感受一下

例题洛谷P3807 【模板】卢卡斯定理

这个题主要就是应用\(2\)注意除法的时候要转化成乘他的逆元

\(Code:\)

#include <cstdio>
#include <iostream>
#define int long long 
using namespace std;
const int N = 100000;
int T, a[N], n, m, p;
int read() {
	int s = 0, w = 1;
	char ch = getchar();
	while(!isdigit(ch)) {if(ch == '-') w = -1; ch = getchar();}
	while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = getchar();}
	return s * w;
}
int inv(int x, int y, int p) {
	y = p - 2;
	int sum = 1;
	while(y) {
		if(y & 1) sum = (sum * x) % p;
		x = (x * x) % p;
		y >>= 1;
	}	
	return sum;
}
int C(int n, int m) {
	if(m > n) return 0;
	return (a[n] * (inv(a[m], p - 2, p) % p) * (inv(a[n - m], p - 2, p))) % p;
}
int Lucas(int n, int m) {
	if(!m) return 1;
	return (Lucas(n / p, m / p) * (C(n % p, m % p) % p)) % p;
}
signed main() {
	T = read();
	a[0] = 1;
	while(T--) {
		n = read(), m = read(), p = read();
		for(int i = 1; i <= p; i++) a[i] = (a[i - 1] * i) % p;
		cout << Lucas(n + m, n) << endl;
	}
	return 0;
}

谢谢收看,祝身体健康!

posted @ 2019-11-01 11:11  lzpclxf  阅读(214)  评论(0编辑  收藏  举报