對組合數取模

看這個以前建議先看一下n!……html

對於組合數咱們能夠將其表示成階乘的形式:C(n,k)= 。那咱們不妨把這三個階乘所有表示成上個專題的形式。這樣的話,若是對於e1>e2+e3就能夠被p整除,e1=e2+e3就沒法被p整除。在沒法被整除的狀況下C(n,k)=a1(a2a3)-1ide

 

1 int mod_comb (int n, int k, int p){
2     if (n<0||k<0||n<k) return 0;
3     int a1=mod_fact(n,p,e1),a2=mod_fact(k,p,e2),a3=mod_fact(n-k,p,e3);
4     if (e1>e2+e3)return 0;
5     return a1*mod_inverse(a2*a3%p, p) %p;
6 }
View Code

 

 

 

另外,咱們也能夠用Lucas來求。spa

Lucas定理:咱們令n=sp+q , m=tp+r(q,r ≤p)則有3d

具體證實以下:code

首先咱們先來證實一個簡單的算式:(f!=p&&f!=0)htm

C(p , f)%p= p!/(f!(p-f)!)%p由於p是素數,而且分母上的f和(p-f)都要比p要小,也就是說在分母上沒有數能夠把p約去,因此C(p,f) %p必定等於0。blog

證實完了這個算式,咱們就能夠開始證實盧卡斯定理。get

對於(1+x)sp+q≡(1+x)sp×(1+x)q≡((1+x)p)s×(1+x)q≡(根據二項式定理展開,而後在有上面的公式,因此咱們能夠獲得)(1+xp)s×(1+x)q≡(再根據二項式定理展開)≡ (mod p)io

最終咱們能夠獲得event

下面咱們來計算一下左右兩邊xtp+r的係數:

左邊=C(sp+q ,tp+r);右邊=C(s ,t)×C(q, r)

由於左邊=右邊,因此咱們最後獲得了盧卡斯定理。

有了盧卡斯定理,咱們就有了這樣的代碼,這個代碼真的很好理解

1 int Lucas(int n,int m,int p){
2     long long ans=1;
3     while(n&&m&&ans){
4         ans*=comb(n%p,m%p,p)%p;//comb()求組合數
5         n/=p;m/=p;
6     }
7     return ans;
8 }
View Code
相關文章
相關標籤/搜索