組合數 求組合數的幾種方法總結

2021-08-04 12:16:02 字數 1732 閱讀 4248

求c(n,m)%mod的方法總結

1.當n,m都很小的時候可以利用楊輝三角直接求。 

c(n,m)=c(n-1,m)+c(n-1,m-1);

2.利用乘法逆元。 

乘法逆元:(a/b)%mod=a*(b^(mod-2)) mod為素數。 

逆元可以利用擴充套件歐幾里德或尤拉函式求得:

1).擴充套件歐幾里德:b*x+p*y=1 有解,x就是所求

2).費馬小定理:b^(p-1)=1(mod p),故b*b^(p-2)=1(mod p),所以x=b^(p-2)(

(1) n!/(m!*(n-m)! =x%p ,先對算出n!、m!、(n-m)!對p取模的餘數,就轉換為a/b=x%p;因為p為素數,所以等價於bx+py=a;然後用擴充套件的歐幾里得定理算出 bx』+py』=1的解,x=x』*a,就得到了最終的x的值,即c(m,n)%p得值。

(2).逆元 其實如果mod是素數 則b的逆元其實就是b^(mod-2) 

也就是 (m!(n-m)!)的逆元為 (m!(n-m)!)p-2 ;

int inv(int a)   

ll c(ll n,ll m)

return up * inv(down) % mod;

}

3.當n和m比較大,mod是素數且比較小的時候(10^5左右),通過lucas定理計算

lucas定理:a、b是非負整數,p是質數。a b寫成p進製:a=a[n]a[n-1]…a[0],b=b[n]b[n-1]…b[0]。 

則組合數c(a,b)與c(a[n],b[n])c(a[n-1],b[n-1])…*c(a[0],b[0]) mod p同餘 

即:lucas(n,m,p)=c(n%p,m%p)*lucas(n/p,m/p,p)

#include

//#include

using

namespace

std;

typedef

long

long ll;

int quick_power_mod(int a,int b,int m)

base = (base*base) %m;

b>>=1;

}return result;

}//計算組合數取模

ll comp(ll a, ll b, int p)

ans = (ca*quick_power_mod(cb, p - 2, p)) % p;

return ans;

}ll lucas(ll n, ll m, ll p)

return ans;

}int main()

c(n % mod, m % mod) % mod; 如果太大還是利用上面的逆元來處理。

半預處理 

由於lucas定理保證了階乘的數均小於p,所以可以講所有的階乘先預處理,優化c(n,m) 

mod的要求:p<10^6,且為素數 

有效範圍:1<=n,m<=10^9

//半預處理  

const ll maxn = 100000;

ll fac[maxn+100];

void init(int

mod)

} //半預處理逆元求c(n,m)%mod

ll c(ll n, ll m)

4.還有一種就是分解質因子,這個比較麻煩。 

組合數學 求組合數

對於求組合數,要根據所給資料範圍來選擇合適的演算法 這道題中所給的資料範圍適合用打表的方法直接暴力求解 先用4e6的複雜度預處理出所有的情況,再用1e4的複雜度完成詢問即可 include using namespace std const int n 2010 const int mod 1e9 ...

Numpy 組合陣列的幾種方法

來自 python資料分析基礎教程 numpy 學習指南 第2版 下面將介紹組合陣列的幾種方法 0.建立兩個3 3的陣列 from numpy import a arange 9 reshape 3,3 print a b 2 a print b 得到結果 0 1 2 3 4 5 6 7 8 0 2...

吉首 組合數 求組合數因子個數

時間限制 1 sec 記憶體限制 128 mb 求組合數c n,m 以及c n,m 因子個數。n和m,其中0 m n 50,以eof結束。該組合數結果。3 2 4 23 2 6 4先利用楊輝三角求出組合數,然後就是求出因子數了 求因子數 素數分解的唯一性,乙個數可以被分解成若干素數相乘 p1 x1 ...