【模板】卢卡斯定理

Lucas定理是用来求 C n m mod p 的值。其中: n , m 是非负整数, p 素数。一般用于 n , m 很大而 p 很小或 n , m 不大且都大于 p 的情形。

Lucas定理结论:

  • L u c a s ( n , m , p ) = C ( n mod p , m mod p , p ) L u c a s ( n / p , m / p , p )

    其中当 m = 0 时, L u c a s ( n , m , p ) = 1

    C ( n , m , p ) = C n m mod p = m ! n ! ( n m ) ! mod p = m ! ( n m ) ! ( n ! ) 1 mod p = m ! ( n m ) ! ( n ! ) p 2 mod p

    其中第三步中 ( n ! ) 1 = ( n ! ) p 2 是应用了 p 是素数这一条件,不明白的可以去看看乘法逆元

实现的时候还要考虑到组合数的几个性质:

  • n < m C n m = 0
  • C n m = C n n m

C o d e

LL FastPower(LL a, LL p, LL k) {
    LL ans = 1;
    while (p) {
        if (p & 1)  ans = (ans * a) % k;
        a = (a * a) % k;
        p >>= 1;
    }
    return ans;
}
LL C(int n, int m, int p) {
    if (n < m) return 0;
    if (m > n - m) m = n - m;
    LL s1 = 1, s2 = 1;
    for (int i = 0; i < m; i++) {
        s1 = s1 * (n - i) % p;
        s2 = s2 * (i + 1) % p;
    }
    return s1 * FastPower(s2, p - 2, p) % p;
}
LL Lucas(int n, int m, int p) {
    if (m == 0) return 1;
    return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}

猜你喜欢

转载自blog.csdn.net/Diogenes_/article/details/81029561