1. 程式人生 > >【模板】盧卡斯定理

【模板】盧卡斯定理

Lucas定理是用來求 Cnmmodp 的值。其中:n, m 是非負整數,p素數。一般用於 n,m 很大而 p 很小或 n,m 不大且都大於 p 的情形。

Lucas定理結論:

  • Lucas(n,m,p)=C(nmodp,mmodp,p)Lucas(n/p,m/p,p)

    其中當 m=0 時,Lucas(n,m,p)=1

    C(n,m,p)=Cnmmodp=m!n!(nm)!modp=m!(nm)!(n!)1modp=m!(nm)!(n!)p2modp

    其中第三步中 (n!)1=(n!)p2 是應用了 p 是素數這一條件,不明白的可以去看看乘法逆元

實現的時候還要考慮到組合數的幾個性質:

  • n<mCnm=0
  • Cnm=Cnnm

Code

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; }