关于卢卡斯定理

关于卢卡斯定理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 
#include 
#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;
}

谢谢收看,祝身体健康!

你可能感兴趣的:(关于卢卡斯定理)