c nm
modp
=cn/
pm/p
×cnm
odpm
modp
modp
c_n^m \mod p=c_^ \times c_^ \mod p
cnmmo
dp=c
n/pm
/p×
cnmo
dpmm
odp
modp
,p為素數
int
qpow
(ll b,
int n,
int mod)
return res;
}int fac[maxn]
;void
init
(int p)
intc
(int n,
int m,
int p)
intlucas
(ll n,ll m,
int p)
return ans;
}
取模時,需要注意 n < m 的情況,此時為 0
1、線性推逆元,在只需要初始化一次的時候使用比較好
const
int n=
5e5;
int fac[n+10]
,finv[n+10]
;void
init()
intc
(int n,
int m)
2、推出階乘之後,用費爾馬小定理計算逆元
int fac[maxn]
;void
init
(int p)
intc
(int n,
int m,
int p)
3、直接用組合式公式計算
ll c
(ll a,ll b,ll p)
return ca*
qpow
(cb,p-
2,p)
%p;}
4、不需要取模時,用楊輝三角
ll c[
1000][
1000];
void
init()
}
#include .h>
#define ll long
long
using namespace std;
const
int maxn=
1e5+
5,maxm=
1e5+5;
intqpow
(ll b,
int n,
int mod)
return res;
}int fac[maxn]
;void
init
(int p)
intc
(int n,
int m,
int p)
intlucas
(ll n,ll m,
int p)
return ans;
}int t,n,m,p;
intmain()
return0;
}
盧卡斯 Lucas 定理
之前有寫過一篇部落格是求組合數 取模 的兩種方法。那篇文章裡介紹的方法其實也還有侷限性,pascal打表由於記憶體的限制一般只用於求取1000以內的組合數,而使用逆元套公式的方法其實也只適用於求取的組合數 c n,m p中,n 和 m均不大於要求的模數 p 這樣就導致了乙個很尷尬的問題 如果要求取的...
盧卡斯定理Lucas
在數論中,lucas 定理用於快速計算 c m n p 即證明 c m n prod kc 其中 m i 為 m 的因式分解,n i 為 n 的因式分解,p 為質數。由 edward lucas 在1878年提出。證明 首先我們將 c i p 進行一下變式即 c i j frac 提出來乙個 fra...
盧卡斯定理 Lucas
當 p 為質數,1 le m le n 時,求組合數 c bmod 對於質數 p,有 begin c equiv c cdot c pmod end 其中 n p 和 m p 為整除。引理1 begin c equiv frac cdot c equiv 0 pmod end 引理1證明 begin...