总结:Lucas定理

证明并不会

公式: Cyx mod p= Cymodpxmodp * Lucasy/px/p

当然答案是要递归得出的。

限制条件:

1.因为求组合数是用暴力方法求的,所以p不能太大
2.组合数记得mod,用逆元来解决
3.要判断一些特殊情况,防止RE,
如: Lucasy/px/p 中y=0的情况以及 Cyx 中x比y小的情都要特判掉(返回 1或者0)

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

代码如下:

#include
#include
using namespace std;
const int maxn=100005;
long long T,n,m,tt,pow[maxn];
long long qsm(long long x,long long y) {
    long long ret=1ll,p=x;
    while (y>0) {
        if (y%2ll==1ll) ret=(ret*p)%tt;
        y=y/2; p=(p*p)%tt;
    }
    return ret;
}
long long c(long long x,long long y) {
    if (x>y) return 0;
    return ((pow[y]*qsm((pow[y-x]*pow[x])%tt,tt-2))%tt)%tt;
}
long long lucas(long long x,long long y) {
    if (x==0) return 1;
    if (xreturn c(x,y);
    else return (c(x%tt,y%tt)*lucas(x/tt,y/tt))%tt;
}
int main(){
    scanf("%lld",&T);
    while (T--) {
        scanf("%lld %lld %lld",&n,&m,&tt);
        pow[0]=1ll;
        for (int i=1;i<=100000;i++) pow[i]=(pow[i-1]*i)%tt;
        printf("%lld\n",lucas(n,m+n));
    }
    return 0;
}

你可能感兴趣的:(知识整理)