Lucas 定理

Lucas 定理用于求解大组合数取模的问题,其中模数必须为素数。正常的组合数运算可以通过递推公式求解(详见排列组合),但当问题规模很大,而模数是一个不大的质数的时候,就不能简单地通过递推求解来得到答案,需要用到 Lucas 定理。

求解方式

Lucas 定理内容如下:对于质数 p p p,有

( n m ) m o d p = ( ⌊ n / p ⌋ ⌊ m / p ⌋ ) ⋅ ( n m o d p m m o d p ) m o d p \binom{n}{m}\bmod p = \binom{\left\lfloor n/p \right\rfloor}{\left\lfloor m/p\right\rfloor}\cdot\binom{n\bmod p}{m\bmod p}\bmod p (mn​)modp=(⌊m/p⌋⌊n/p⌋​)⋅(mmodpnmodp​)modp

观察上述表达式,可知 n m o d p n\bmod p nmodp 和 m m o d p m\bmod p mmodp 一定是小于 p p p 的数,可以直接求解, ( ⌊ n / p ⌋ ⌊ m / p ⌋ ) \displaystyle\binom{\left\lfloor n/p \right\rfloor}{\left\lfloor m/p\right\rfloor} (⌊m/p⌋⌊n/p⌋​) 可以继续用 Lucas 定理求解。这也就要求 p p p 的范围不能够太大,一般在 1 0 5 10^5 105 左右。边界条件:当 m = 0 m=0 m=0 的时候,返回 1 1 1。

时间复杂度为 O ( f ( p ) + g ( n ) log ⁡ n ) O(f(p) + g(n)\log n) O(f(p)+g(n)logn),其中 f ( n ) f(n) f(n) 为预处理组合数的复杂度, g ( n ) g(n) g(n) 为单次求组合数的复杂度。

ll qpow(ll x, ll n, ll mod) {ll ans = 1;while (n) {if (n & 1)ans = (ans * x) % mod;x = (x * x) % mod;n >>= 1;}return ans % mod;
}
ll C(ll a, ll b, ll p){//通过定理求组合数C(a, b)if (a < b) return 0;ll x = 1, y = 1;// x是分子,y是分母for (int i = a, j = 1; j <= b; i--, j++){x = x * i % p;y = y * j % p;}return x * qpow(y, p - 2, p) % p;
}
ll lucas(ll a, ll b, int p){//lucas定理求组合数if (a < p && b < p) return C(a, b, p);return C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}

素数在阶乘中的幂次

Legengre 在 1808 年指出 n ! n! n! 中含有的素数 p p p 的幂次为 ∑ j ≥ 1 ⌊ n / p j ⌋ \sum_{j\geq 1}\lfloor n/p^j\rfloor ∑j≥1​⌊n/pj⌋。

证明:将 n ! n! n! 记为 1 × 2 × ⋯ × p × ⋯ × 2 p × ⋯ × ⌊ n / p ⌋ p × ⋯ × n 1\times 2\times \cdots \times p\times \cdots \times 2p\times \cdots \times \lfloor n/p\rfloor p\times \cdots \times n 1×2×⋯×p×⋯×2p×⋯×⌊n/p⌋p×⋯×n 那么其中 p p p 的倍数有 p × 2 p × ⋯ × ⌊ n / p ⌋ p = p ⌊ n / p ⌋ ⌊ n / p ⌋ ! p\times 2p\times \cdots \times \lfloor n/p\rfloor p=p^{\lfloor n/p\rfloor }\lfloor n/p\rfloor ! p×2p×⋯×⌊n/p⌋p=p⌊n/p⌋⌊n/p⌋! 然后在 ⌊ n / p ⌋ ! \lfloor n/p\rfloor ! ⌊n/p⌋! 中继续寻找 p p p 的倍数即可,这是一个递归的过程。为了方便记 ν ( n ! ) = ∑ j ≥ 1 ⌊ n / p j ⌋ \nu(n!)=\sum_{j\geq 1}\lfloor n/p^j\rfloor ν(n!)=∑j≥1​⌊n/pj⌋。

另一种其他地方比较常见的公式,用到了 p 进制下各位数字和:

v p ( n ! ) = n − S p ( n ) p − 1 v_p(n!)=\frac{n-S_p(n)}{p-1} vp​(n!)=p−1n−Sp​(n)​

与等比数列求和公式很相似。由于涉及各位数字和,利用数学归纳法可以轻松证明。

特别地,阶乘中 2 的幂次是:

v 2 ( n ! ) = n − S 2 ( n ) v_2(n!)=n-S_2(n) v2​(n!)=n−S2​(n)

素数在组合数中的幂次

组合数对一个数取模的结果,往往构成分形结构,例如谢尔宾斯基三角形就可以通过组合数模 2 得到。

v p ( C m n ) = S p ( n ) + S p ( m − n ) − S p ( m ) p − 1 v_p(C_m^n)=\frac{S_p(n)+S_p(m-n)-S_p(m)}{p-1} vp​(Cmn​)=p−1Sp​(n)+Sp​(m−n)−Sp​(m)​

如果仔细分析,p 是否整除组合数其实和上下标在 p 进制下减法是否需要借位有关。这就有了 Kummer 定理。

Kummer 定理:p 在组合数 C m n C_m^n Cmn​ 中的幂次,恰好是 p 进制下 m 减掉 n 需要借位的次数。

特别地,组合数中 2 的幂次是:

v 2 ( C m n ) = S 2 ( n ) + S 2 ( m − n ) − S 2 ( m ) v_2(C_m^n)=S_2(n)+S_2(m-n)-S_2(m) v2​(Cmn​)=S2​(n)+S2​(m−n)−S2​(m)

Wilson 定理

对于素数 p p p 有 ( p − 1 ) ! ≡ − 1 ( m o d p ) (p-1)!\equiv -1\pmod p (p−1)!≡−1(modp)。

  • 证明:我们知道在模奇素数 p p p 意义下, 1 , 2 , … , p − 1 1,2,\dots ,p-1 1,2,…,p−1 都存在逆元且唯一,那么只需要将一个数与其逆元配对发现其乘积均为(同余意义下) 1 1 1,但前提是这个数的逆元不等于自身。那么很显然 ( p − 1 ) ! m o d p (p-1)!\bmod p (p−1)!modp 就是逆元等于其自身的数的乘积,这两个数为 ± 1 \pm 1 ±1。在 p p p 为 2 2 2 时单独讨论即可。对于整数 n n n,令 ( n ! ) p (n!)_p (n!)p​ 表示所有小于等于 n n n 但不能被 p p p 整除的正整数的乘积,即 ( n ! ) p = n ! / ( ⌊ n / p ⌋ ! p ⌊ n / p ⌋ ) (n!)_p=n!/(\lfloor n/p\rfloor !p^{\lfloor n/p\rfloor}) (n!)p​=n!/(⌊n/p⌋!p⌊n/p⌋)。
  • Wilson 定理指出 ( p ! ) p = ( p − 1 ) ! ≡ − 1 ( m o d p ) (p!)_p=(p-1)!\equiv -1\pmod p (p!)p​=(p−1)!≡−1(modp) 且可被推广至模素数 p p p 的幂次。

推论 1

对于素数 p p p 和正整数 q q q 有 ( p q ! ) p ≡ ± 1 ( m o d p q ) (p^q!)_p\equiv \pm 1\pmod{p^q} (pq!)p​≡±1(modpq)。

依然考虑配对一个数与其逆元,也就是考虑关于 m m m 的同余方程 m 2 ≡ 1 ( m o d p q ) m^2\equiv 1\pmod{p^q} m2≡1(modpq) 的根的乘积,当 p q = 2 p^q=2 pq=2 时方程仅有一根,当 p = 2 p=2 p=2 且 q ≥ 3 q\geq 3 q≥3 时有四根为 ± 1 , 2 q − 1 ± 1 \pm 1,2^{q-1}\pm 1 ±1,2q−1±1 其他时候则有两根为 ± 1 \pm 1 ±1。

至此我们对 Wilson 定理的推广中的 ± 1 \pm 1 ±1 有了详细的定义即

( p q ! ) p ≡ { 1 if  p = 2 and  q ≥ 3 , − 1 otherwise. (p^q!)_p\equiv \begin{cases}1&\text{if }p=2\text{ and }q\geq 3,\\-1&\text{otherwise.}\end{cases} (pq!)p​≡{1−1​if p=2 and q≥3,otherwise.​

下文两个推论中的 ± 1 \pm 1 ±1,均特指这样的定义:当模数 p q p^q pq 取 8 及以上的 2 的幂时取 1,其余取 - 1。

推论 2

对于素数 p p p、正整数 q q q、非负整数 n n n 和 N 0 = n m o d p q N_0=n\bmod{p^q} N0​=nmodpq 有 ( n ! ) p ≡ ( ± 1 ) ⌊ n / p q ⌋ ( N 0 ! ) p ( m o d p q ) (n!)_p\equiv (\pm 1)^{\lfloor n/{p^q}\rfloor}(N_0!)_p\pmod{p^q} (n!)p​≡(±1)⌊n/pq⌋(N0​!)p​(modpq)

  • 证明:令 ∏ ′ \displaystyle \prod ' ∏′​ 表示不能被 p p p 整除的数的乘积,有
    ( n ! ) p = ∏ 1 ≤ r ≤ n ′ r = ( ∏ i = 0 ⌊ n / p q ⌋ − 1 ∏ 1 ≤ j ≤ p q ′ ( i p q + j ) ) ( ∏ 1 ≤ j ≤ N 0 ′ ( ⌊ n / p q ⌋ p q + j ) ) ≡ ( ( p q ! ) p ) ⌊ n / p q ⌋ ( N 0 ! ) p ≡ ( ± 1 ) ⌊ n / p q ⌋ ( N 0 ! ) p ( m o d p q ) \begin{aligned} (n!)_p&=\prod_{1\leq r\leq n}'r\\ &=\left(\prod_{i=0}^{\lfloor n/p^q \rfloor -1}\prod_{1\leq j\leq p^q}'(ip^q+j)\right)\left(\prod_{1\leq j\leq N_0}'(\lfloor n/p^q\rfloor p^q+j)\right)\\ &\equiv ((p^q!)_p)^{\lfloor n/p^q\rfloor}(N_0!)_p\\ &\equiv (\pm 1)^{\lfloor n/p^q\rfloor}(N_0!)_p\pmod{p^q} \end{aligned} (n!)p​​=1≤r≤n∏′​r=⎝⎛​i=0∏⌊n/pq⌋−1​1≤j≤pq∏′​(ipq+j)⎠⎞​⎝⎛​1≤j≤N0​∏′​(⌊n/pq⌋pq+j)⎠⎞​≡((pq!)p​)⌊n/pq⌋(N0​!)p​≡(±1)⌊n/pq⌋(N0​!)p​(modpq)​
    将 1 × 2 × 3 × ⋯ × n 1\times 2\times 3\times \cdots \times n 1×2×3×⋯×n 记为 ( 0 × p q + 1 ) × ( 0 × p q + 2 ) × ⋯ × ( ⌊ n / p q ⌋ p q + N 0 ) (0\times p^q+1)\times (0\times p^q+2)\times \cdots \times (\lfloor n/p^q\rfloor p^q+N_0) (0×pq+1)×(0×pq+2)×⋯×(⌊n/pq⌋pq+N0​) 就得到了上述第二行。
    至此得到了

推论 3

对于素数 p p p 和正整数 q q q 和非负整数 n n n 有

n ! p ∑ j ≥ 1 ⌊ n p j ⌋ ≡ ( ± 1 ) ∑ j ≥ q ⌊ n p j ⌋ ∏ j ≥ 0 ( N j ! ) p ( m o d p q ) \frac{n!}{p^{\sum_{j\geq 1}\lfloor \frac{n}{p^j}\rfloor}}\equiv (\pm 1)^{\sum_{j\geq q}\lfloor \frac{n}{p^j}\rfloor}\prod_{j\geq 0}(N_j!)_p\pmod{p^q} p∑j≥1​⌊pjn​⌋n!​≡(±1)∑j≥q​⌊pjn​⌋∏j≥0​(Nj​!)p​(modpq)

其中 N j = ⌊ n / p j ⌋ m o d p q N_j=\lfloor n/p^j\rfloor \bmod{p^q} Nj​=⌊n/pj⌋modpq 而 ± 1 \pm 1 ±1 与上述相同。

记 r = n − m r=n-m r=n−m 且 n > m n > m n>m 有

( ± 1 ) ∑ j ≥ q ( ⌊ n / p j ⌋ − ⌊ m / p j ⌋ − ⌊ r / p j ⌋ ) p ν ( n ! ) − ν ( m ! ) − ν ( r ! ) ( n m ) ≡ n ! / p ν ( n ! ) ( m ! / p ν ( m ! ) ) ( r ! / p ν ( r ! ) ) ( m o d p q ) \frac{(\pm 1)^{\sum_{j\geq q}\left(\lfloor n/p^j\rfloor -\lfloor m/p^j\rfloor -\lfloor r/p^j\rfloor\right)}}{p^{\nu(n!)-\nu(m!)-\nu(r!)}}\binom{n}{m}\equiv \frac{n!/p^{\nu(n!)}}{(m!/p^{\nu(m!)})(r!/p^{\nu(r!)})}\pmod{p^q} pν(n!)−ν(m!)−ν(r!)(±1)∑j≥q​(⌊n/pj⌋−⌊m/pj⌋−⌊r/pj⌋)​(mn​)≡(m!/pν(m!))(r!/pν(r!))n!/pν(n!)​(modpq)

右边的分母中括号内的项均在模 p q p^q pq 意义下均存在逆元,可直接计算,而 ± 1 \pm 1 ±1 的与上述相同。

exLucas 定理

Lucas 定理中对于模数 p p p 要求必须为素数,那么对于 p p p 不是素数的情况,就需要用到 exLucas 定理。

求解思路

第一部分:中国剩余定理

要求计算二项式系数 ( n m ) m o d M \binom{n}{m}\bmod M (mn​)modM,其中 M M M 可能为合数。

考虑利用中国剩余定理 合并答案,这种情况下我们只需求出 ( n m ) m o d p q \binom{n}{m}\bmod p^q (mn​)modpq 的值即可(其中 p p p 为素数且 q q q 为正整数)。

根据 唯一分解定理,将 p p p 质因数分解:

p = q 1 α 1 ⋅ q 2 α 2 ⋯ q r α r = ∏ i = 1 r q i α i p={q_1}^{\alpha_1}\cdot{q_2}^{\alpha_2}\cdots{q_r}^{\alpha_r}=\prod_{i=1}^{r}{q_i}^{\alpha_i} p=q1​α1​⋅q2​α2​⋯qr​αr​=i=1∏r​qi​αi​

对于任意 i , j i,j i,j,有 q i α i {q_i}^{\alpha_i} qi​αi​ 与 q j α j {q_j}^{\alpha_j} qj​αj​ 互质,所以可以构造如下 r r r 个同余方程:

{ a 1 ≡ ( n m ) ( m o d q 1 α 1 ) a 2 ≡ ( n m ) ( m o d q 2 α 2 ) ⋯ a r ≡ ( n m ) ( m o d q r α r ) \left\{ \begin{aligned} a_1\equiv \displaystyle\binom{n}{m}&\pmod {{q_1}^{\alpha_1}}\\ a_2\equiv \displaystyle\binom{n}{m}&\pmod {{q_2}^{\alpha_2}}\\ &\cdots\\ a_r\equiv \displaystyle\binom{n}{m}&\pmod {{q_r}^{\alpha_r}}\\ \end{aligned} \right. ⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧​a1​≡(mn​)a2​≡(mn​)ar​≡(mn​)​(modq1​α1​)(modq2​α2​)⋯(modqr​αr​)​

我们发现,在求出 a i a_i ai​ 后,就可以用中国剩余定理求解出 ( n m ) \displaystyle\binom{n}{m} (mn​)。

第二部分:移除分子分母中的素数

根据同余的定义, a i = ( n m ) m o d q i α i \displaystyle a_i=\binom{n}{m}\bmod {q_i}^{\alpha_i} ai​=(mn​)modqi​αi​,问题转化成,求 ( n m ) m o d q k \displaystyle \binom{n}{m} \bmod q^k (mn​)modqk( q q q 为质数)的值。

根据组合数定义 ( n m ) = n ! m ! ( n − m ) ! \displaystyle \binom{n}{m} = \frac{n!}{m! (n-m)!} (mn​)=m!(n−m)!n!​, ( n m ) m o d q k = n ! m ! ( n − m ) ! m o d q k \displaystyle \binom{n}{m} \bmod q^k = \frac{n!}{m! (n-m)!} \bmod q^k (mn​)modqk=m!(n−m)!n!​modqk。

由于式子是在模 q k q^k qk 意义下,所以分母要算乘法逆元。

同余方程 a x ≡ 1 ( m o d p ) ax \equiv 1 \pmod p ax≡1(modp)(即乘法逆元)有解 的充要条件为 gcd ⁡ ( a , p ) = 1 \gcd(a,p)=1 gcd(a,p)=1(裴蜀定理),

然而 无法保证有解,发现无法直接求 inv ⁡ m ! \operatorname{inv}_{m!} invm!​ 和 inv ⁡ ( n − m ) ! \operatorname{inv}_{(n-m)!} inv(n−m)!​,

所以将原式转化为:

n ! q x m ! q y ( n − m ) ! q z q x − y − z m o d q k \frac{\frac{n!}{q^x}}{\frac{m!}{q^y}\frac{(n-m)!}{q^z}}q^{x-y-z} \bmod q^k qym!​qz(n−m)!​qxn!​​qx−y−zmodqk

x x x 表示 n ! n! n! 中包含多少个 q q q 因子, y , z y, z y,z 同理。

第三部分:Wilson 定理的推论

问题转化成,求形如:

n ! q x m o d q k \frac{n!}{q^x}\bmod q^k qxn!​modqk

的值。这时可以利用上文 Wilson 定理的推论。如果难以理解,可以看看下面的解释。

一个示例:22! mod 9

先考虑 n ! m o d q k n! \bmod q^k n!modqk,

比如 n = 22 , q = 3 , k = 2 n=22, q=3, k=2 n=22,q=3,k=2 时:

22 ! = 1 × 2 × 3 × 4 × 5 × 6 × 7 × 8 × 9 × 10 × 11 × 12 22!=1\times 2\times 3\times 4\times 5\times 6\times 7\times 8\times 9\times 10\times 11\times 12 22!=1×2×3×4×5×6×7×8×9×10×11×12

× 13 × 14 × 15 × 16 × 17 × 18 × 19 × 20 × 21 × 22 \times 13\times 14\times 15\times 16\times 17\times 18\times 19\times20\times21\times22 ×13×14×15×16×17×18×19×20×21×22

将其中所有 q q q 的倍数提取,得到:

22 ! = 3 7 × ( 1 × 2 × 3 × 4 × 5 × 6 × 7 ) 22!=3^7 \times (1\times 2\times 3\times 4\times 5\times 6\times 7) 22!=37×(1×2×3×4×5×6×7) × ( 1 × 2 × 4 × 5 × 7 × 8 × 10 × 11 × 13 × 14 × 16 × 17 × 19 × 20 × 22 ) \times(1\times 2\times 4\times 5\times 7\times 8\times 10 \times 11\times 13\times 14\times 16\times 17\times 19 \times 20 \times 22 ) ×(1×2×4×5×7×8×10×11×13×14×16×17×19×20×22)

可以看到,式子分为三个整式的乘积:

  1. 是 3 3 3 的幂,次数是 ⌊ n q ⌋ \lfloor\frac{n}{q}\rfloor ⌊qn​⌋;

  2. 是 7 ! 7! 7!,即 ⌊ n q ⌋ ! \lfloor\frac{n}{q}\rfloor! ⌊qn​⌋!,由于阶乘中仍然可能有 q q q 的倍数,考虑递归求解;

  3. 是 n ! n! n! 中与 q q q 互质的部分的乘积,具有如下性质:
    1 × 2 × 4 × 5 × 7 × 8 ≡ 10 × 11 × 13 × 14 × 16 × 17 ( m o d 3 2 ) 1\times 2\times 4\times 5\times 7\times 8\equiv10 \times 11\times 13\times 14\times 16\times 17 \pmod{3^2} 1×2×4×5×7×8≡10×11×13×14×16×17(mod32),
    即: ∏ i , ( i , q ) = 1 q k i ≡ ∏ i , ( i , q ) = 1 q k ( i + t q k ) ( m o d q k ) \displaystyle \prod_{i,(i,q)=1}^{q^k}i\equiv\prod_{i,(i,q)=1}^{q^k}(i+tq^k) \pmod{q^k} i,(i,q)=1∏qk​i≡i,(i,q)=1∏qk​(i+tqk)(modqk)( t t t 是任意正整数)。
    ∏ i , ( i , q ) = 1 q k i \displaystyle \prod_{i,(i,q)=1}^{q^k}i i,(i,q)=1∏qk​i 一共循环了 ⌊ n q k ⌋ \displaystyle \lfloor\frac{n}{q^k}\rfloor ⌊qkn​⌋ 次,暴力求出 ∏ i , ( i , q ) = 1 q k i \displaystyle \prod_{i,(i,q)=1}^{q^k}i i,(i,q)=1∏qk​i,然后用快速幂求 ⌊ n q k ⌋ \displaystyle \lfloor\frac{n}{q^k}\rfloor ⌊qkn​⌋ 次幂。
    最后要乘上 ∏ i , ( i , q ) = 1 n m o d q k i \displaystyle \prod_{i,(i,q)=1}^{n \bmod q^k}i i,(i,q)=1∏nmodqk​i,即 19 × 20 × 22 19\times 20\times 22 19×20×22,显然长度小于 q k q^k qk,暴力乘上去。

上述三部分乘积为 n ! n! n!。最终要求的是 n ! q x m o d q k \frac{n!}{q^x}\bmod{q^k} qxn!​modqk。

所以有:

n ! = q ⌊ n q ⌋ ⋅ ( ⌊ n q ⌋ ) ! ⋅ ( ∏ i , ( i , q ) = 1 q k i ) ⌊ n q k ⌋ ⋅ ( ∏ i , ( i , q ) = 1 n m o d q k i ) n! = q^{\left\lfloor\frac{n}{q}\right\rfloor} \cdot \left(\left\lfloor\frac{n}{q}\right\rfloor\right)! \cdot {\left(\prod_{i,(i,q)=1}^{q^k}i\right)}^{\left\lfloor\frac{n}{q^k}\right\rfloor} \cdot \left(\prod_{i,(i,q)=1}^{n\bmod q^k}i\right) n!=q⌊qn​⌋⋅(⌊qn​⌋)!⋅⎝⎛​i,(i,q)=1∏qk​i⎠⎞​⌊qkn​⌋⋅⎝⎛​i,(i,q)=1∏nmodqk​i⎠⎞​

于是:

n ! q ⌊ n q ⌋ = ( ⌊ n q ⌋ ) ! ⋅ ( ∏ i , ( i , q ) = 1 q k i ) ⌊ n q k ⌋ ⋅ ( ∏ i , ( i , q ) = 1 n m o d q k i ) \frac{n!}{q^{\left\lfloor\frac{n}{q}\right\rfloor}} = \left(\left\lfloor\frac{n}{q}\right\rfloor\right)! \cdot {\left(\prod_{i,(i,q)=1}^{q^k}i\right)}^{\left\lfloor\frac{n}{q^k}\right\rfloor} \cdot \left(\prod_{i,(i,q)=1}^{n\bmod q^k}i\right) q⌊qn​⌋n!​=(⌊qn​⌋)!⋅⎝⎛​i,(i,q)=1∏qk​i⎠⎞​⌊qkn​⌋⋅⎝⎛​i,(i,q)=1∏nmodqk​i⎠⎞​

( ⌊ n q ⌋ ) ! \displaystyle \left(\left\lfloor\frac{n}{q}\right\rfloor\right)! (⌊qn​⌋)! 同样是一个数的阶乘,所以也可以分为上述三个部分,于是可以递归求解。

等式的右边两项不含素数 q。事实上,如果直接把 n 的阶乘中所有 q 的幂都拿出来,等式右边的阶乘也照做,这个等式可以直接写成:

n ! q x = ( ⌊ n q ⌋ ) ! q x ′ ⋅ ( ∏ i , ( i , q ) = 1 q k i ) ⌊ n q k ⌋ ⋅ ( ∏ i , ( i , q ) = 1 n m o d q k i ) \frac{n!}{q^{x}} = \frac{\left(\left\lfloor\frac{n}{q}\right\rfloor\right)!}{q^{x'}} \cdot {\left(\prod_{i,(i,q)=1}^{q^k}i\right)}^{\left\lfloor\frac{n}{q^k}\right\rfloor} \cdot \left(\prod_{i,(i,q)=1}^{n\bmod q^k}i\right) qxn!​=qx′(⌊qn​⌋)!​⋅⎝⎛​i,(i,q)=1∏qk​i⎠⎞​⌊qkn​⌋⋅⎝⎛​i,(i,q)=1∏nmodqk​i⎠⎞​

式中的 x 和 x’都表示把分子中所有的素数 q 都拿出来。改写成这样,每一项就完全不含 q 了。

递归的结果,三个部分中,左边部分随着递归结束而自然消失,中间部分可以利用 Wilson 定理的推论 0,右边部分就是推论 2 中的 ∏ j ≥ 0 ( N j ! ) p \prod_{j\geq 0}(N_j!)_p ∏j≥0​(Nj​!)p​。

下面这种写法,拥有单次询问 O ( p l o g p ) O(plogp) O(plogp) 的时间复杂度。其中 int inverse(int x) 函数返回 x x x 在模 p p p 意义下的逆元。
P4720 【模板】扩展卢卡斯定理/exLucas

#include<bits/stdc++.h>
#include <unordered_map>
using namespace std;
template<class...Args>
void debug(Args... args) {//Parameter packauto tmp = { (cout << args << ' ', 0)... };cout << "\n";
}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>pll;
typedef pair<int, int>pii;
const ll N = 1e6 + 5;
const ll INF = 0x7fffffff;
const ll MOD = 1e9 + 7;ll extend_gcd(ll a, ll b, ll& x, ll& y) {if (!b) {x = 1; y = 0;return a;}ll d = extend_gcd(b, a % b, y, x);y -= (a / b) * x;return d;
}
ll mod_inverse(ll a, ll m) {ll x, y;extend_gcd(a, m, x, y);return (m + x % m) % m;
}
ll qpow(ll x, ll n, ll mod) {ll ans = 1;while (n) {if (n & 1)ans = (ans * x) % mod;x = (x * x) % mod;n >>= 1;}return ans % mod;
}
ll calc(ll n, ll x, ll P) {if (!n) return 1;ll s = 1;for (ll i = 1; i <= P; i++)if (i % x) s = s * i % P;s = qpow(s, n / P, P);for (ll i = n / P * P + 1; i <= n; i++)if (i % x) s = i % P * s % P;return s * calc(n / x, x, P) % P;
}
ll multilucas(ll n, ll m, ll x, ll P) {ll cnt = 0;for (ll i = n; i; i /= x) cnt += i / x;for (ll i = m; i; i /= x) cnt -= i / x;for (ll i = n - m; i; i /= x) cnt -= i / x;return qpow(x, cnt, P) % P * calc(n, x, P) % P * mod_inverse(calc(m, x, P), P) % P * mod_inverse(calc(n - m, x, P), P) % P;
}
ll CRT(int n, vector<ll> p, vector<ll> a) {ll cnt = 1, ans = 0;for (int i = 1; i <= n; i++) cnt = cnt * p[i];for (int i = 1; i <= n; i++) {ll m = cnt / p[i], x, y;extend_gcd(m, p[i], x, y);ans = (ans + a[i] * m * x % cnt) % cnt;}return (ans % cnt + cnt) % cnt;
}
ll exlucas(ll n, ll m, ll P) {ll cnt = 0;vector<ll> p(20), a(20);for (ll i = 2; i * i <= P; i++) {if (P % i == 0) {p[++cnt] = 1;while (P % i == 0) p[cnt] = p[cnt] * i, P /= i;a[cnt] = multilucas(n, m, i, p[cnt]);}}if (P > 1) p[++cnt] = P, a[cnt] = multilucas(n, m, P, P);return CRT(cnt, p, a);
}int main() {ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);ll n, m, p;cin >> n >> m >> p;cout << exlucas(n, m, p) << "\n";return 0;
}

若不考虑 excrt 的复杂度,通过预处理 n ! n 以 内 的 p 的 所 有 倍 数 的 乘 积 m o d p \frac{n!}{n以内的p的所有倍数的乘积}\bmod{p} n以内的p的所有倍数的乘积n!​modp,可以使时间复杂度优化至单次 O ( p + log ⁡ p ) O(p + \log p) O(p+logp)。而如果 p 是固定的,我们在一开始就可以对 p 进行分解,并进行预处理,可以达到总复杂度 O ( p + T log ⁡ p ) O(p + T\log p) O(p+Tlogp)。

Lucas 定理学习笔记相关推荐

  1. lucas定理 学习笔记

    lucas定理 学习笔记 文章目录 lucas定理 学习笔记 介绍 combination 题目描述 输入格式 输出格式 样例 输入样例1 输出样例2 分析 code 扩展lucas 介绍 lucas ...

  2. lucas定理、拓展lucas定理学习小结

    lucas定理 正题 首先,这玩意就是下面这个式子: C m n % p = C m / p n / p ∗ C m % p n % p % p C_m^n\%p=C_{m/p}^{n/p}*C_{m ...

  3. [MIT]微积分重点 第十七课 六函数、六法则和六定理 学习笔记

    1.六函数 积分 六函数 导数 xn+1/(n+1)x^{n+1}/(n+1)xn+1/(n+1) xnx^nxn nxn−1nx^{n-1}nxn−1 −cos⁡x-\cos x−cosx sin⁡ ...

  4. 二部图Hall定理学习笔记

    离散数学PPT: Hall定理 定理(Hall定理) 设二部图G=<V1,V2,E>中,|V1|≤|V2|. G中存在从V1到V2的完备匹配当且仅当V1中任意k 个顶点至少与V2中的k个顶 ...

  5. Burnside引理和Polya定理学习笔记

    前言 求·······的方案数 循环同构算一种 一脸懵逼 (于是我觉得系统的学一遍Burnside引理和Polya定理) 正文 置换 置换的概念 对于一个排列aia_iai​ 我们想成iii输进去会出 ...

  6. 基尔霍夫矩阵矩阵树定理学习笔记

    背景: 好多东西没学. 勇士被快船惊天大逆转!!! 快船NBNBNB. 紧接着下午打球水杯被搞烂了......... 正题: Part1Part1Part1行列式: 对于一个n∗nn*nn∗n的矩阵A ...

  7. 傅里叶变换与香农采样定理学习笔记

    1. 傅里叶变换入门 无公式,最直观了解什么是傅里叶变换? 傅里叶分析之掐死教程(完整版)更新于2014.06.06 数学公式基础推导出傅里叶变换与反变换 纯干货数学推导_傅里叶级数与傅里叶变换_Pa ...

  8. 中国剩余定理(CRT)孙子定理学习笔记

    在<孙子算经>中有这样一个问题:"今有物不知其数,三三数之剩二(除以3余2),五五数之剩三(除以5余3),七七数之剩二(除以7余2),问物几何?"这个问题称为" ...

  9. 洛谷4455 [CQOI2018]社交网络 (有向图矩阵树定理)(学习笔记)

    sro_ptx_orz qwq算是一个套路的记录 对于一个有向图来说 如果你要求一个外向生成树的话,那么如果存在一个\(u\rightarrow v\)的边 那么\(a[u][v]--,a[v][v] ...

最新文章

  1. 在Ubuntu 14.04 64bit上安装下载管理器FlareGet 4.2.92
  2. Excel 的点点滴滴
  3. 数据流技术在GPU和大数据处理中的应用
  4. MiniDao1.8.3 版本发布,轻量级Java持久化框架
  5. 语义分割江湖的那些事儿——从旷视说起
  6. java增删改查_只会增删改查的Java程序员该如何发展
  7. MS SQL开发经典
  8. linux jdk环境变量配置不生效_Linux服务器JDK环境变量配置
  9. .Net Remoting与Web Service
  10. matlab用于系统框图建模的函数,matlab工具箱与s份imulink.ppt
  11. 电脑连接移动设备android驱动程序,手机连接电脑驱动程序下载汇总
  12. Android DNK开发错误记录
  13. 数据建模 - 概念模型,逻辑模型,物理模型 的区别以及建模方式
  14. ​单页应用程序是如何打破网页设计的?
  15. DISKPART 硬盘只读
  16. Android之TabActivity的使用
  17. Bartender 的二维码QR Code出现编码错误:输入数据包含对所选编码无效的字符
  18. 存储卡 介质受写入保护 U盘无法删除文件 无法新建文件 存储卡无法删除文件 无法新建文件
  19. 【bat】批处理教程之for的/f参数
  20. VBS脚本统计红楼梦中贾宝玉出现的次数

热门文章

  1. ARM协处理器CP15介绍
  2. linux io测试陈旭,陈旭展
  3. 古老密码---凯撒密码
  4. 重构·创新·优化 | 第四届农牧企业数字化创新峰会圆满落幕
  5. 深蓝学院-视觉SLAM课程-第2讲作业
  6. HTML(二)列表与表格的使用
  7. php instanceof not,php instanceof
  8. TestNg之断言Assert
  9. 判断坐标点是否处于某个范围内(射线法)
  10. UVA12657 移动盒子 Boxes in a Line