求組合數(取模)的兩種方法

2022-05-24 14:03:09 字數 885 閱讀 8252

兩種公式配合lucas定理使用更佳

由pascal公式,可知

\[\beginc_n^k=c_^+c_^k\\c_n^0=c_n^n=1\end

\]取二維陣列 \(tc\) ,初始化 \(tc[0][0] = 1\); 打表即可。**最簡單,如下:

const int maxn(1005), mod(100003);

int tc[maxn][maxn]; //tc 表示 table of c

inline int c(int n, int k)

void calcc(int n)

}

計算 \(c_n^k\) 返回內聯函式 \(c_n^k\) 的值即可。

當然我們知道 \(c_n^k=c_n^\),所以上面的**有很多空間和時間的浪費。可以將 \(tc\) 二維陣列轉化為一維陣列儲存,同時,當 \(j>i/2\) 時終止第二層迴圈,新**如下:

const int maxn(10005), mod(100003);

int tc[maxn * maxn]; //tc 表示 table of c

inline int loc(int n, int k) // c(n, k)返回在一維陣列中的位置

inline int c(int n, int k)

void calcc(int n)

}

顯然,由於空間的限制,pascal打表的方式並不適合求取一些比較大的組合數。

所以第二種出現了

因為 \(c_n^m=\dfrac\) ,所以可以預處理1到n的階乘對mod取模的結果,然後用「拓展歐幾里得演算法」或「費馬小定理」或「尤拉定理」求 \(m!\) 和 \(n!\) 的逆元,然後相乘即可(乘的過程中記得取模)

組合數取模 方法彙總

1.利用整數唯一分解定理,求 n 1 m n m m n 1 不論什麼正整數都有且僅僅有一種方法寫出其素因子冪相乘的形式。比方18 2 3 2 a p1 k1 p2 k2 p3 k3 p4 k4 pn kn pi為素數 還有把階層看作乙個數,比m 如何求m 裡面素數2的指數呢?cnt 0 while...

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

求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...

組合數取模的題

聰聰考試 難度級別 c 執行時間限制 1000ms 執行空間限制 262144kb 長度限制 2000000b 試題描述 聰聰是乙個善良可愛 睿智聰慧的好孩子。聰聰是100 的學霸,這一天她在考數學。聰聰很快做到了最後一道題 高一八班有n個人,從1到n編號,一次互判作業時,老師隨機將作業發到這n個人...