Lucas(盧卡斯)定理
公式
$$C_n^m\%p=C_{n/p}^{m/p}*C_{n\%p}^{m\%p}\%p~~(p為素數)$$
程式碼如下
typedef long long ll; ll mod_pow(ll x, ll n, ll mod) { ll res = 1; while (n > 0) { if (n & 1) res = res * x % mod; x = x * x % mod; n >>= 1; } return res; } ll comb(ll n, ll m, ll p) { if (m > n) return 0; ll a = 1, b = 1; m = min(n - m, m); while(m) { a = (a * n--) % p; b = (b * m--) % p; } return a * mod_pow(b, p - 2, p) % p; } ll Lucas(ll n, ll m, ll p) { if (m == 0) return 1; return comb(n % p, m % p, p) * Lucas(n / p, m / p, p) % p; }
例題
解析:m個相同的豆子,放到n個不同的樹裡,有多少種方法。有$C_{n+m}^m$種。具體詳解請看下面的擴充套件中的插板法。
程式碼如下:
#include <iostream> #include <algorithm> using namespace std; typedef long long ll; ll mod_pow(ll x, ll n, ll mod) { ll res = 1; while (n > 0) { if (n & 1) res = res * x % mod; x = x * x % mod; n >>= 1; } return res; } ll comb(ll n, ll m, ll p) { if (m > n) return 0; ll a = 1, b = 1; m = min(n - m, m); while(m) { a = (a * n--) % p; b = (b * m--) % p; } return a * mod_pow(b, p - 2, p) % p; } ll Lucas(ll n, ll m, ll p) { if (m == 0) return 1; return comb(n % p, m % p, p) * Lucas(n / p, m / p, p) % p; } int main(int argc, char* argv[]) { ios::sync_with_stdio(false); cin.tie(0); ll T, n, m, p; cin >> T; while (T--) { cin >> n >> m >> p; cout << Lucas(n + m, m, p) << endl; } return 0; }
擴充套件
插板法
適用型別
一組相同的元素,分成若干不同的組,每組至少一個元素。
例題1
將8個相同的小球放到3個不同的盒子,每個盒子至少放一個球,一共有多少種方法。
解:8個盒子,有7個空,分到3個盒子,需要插2塊板,$C_7^2=21$種。
對於不滿足每組至少一個元素條件的,應該先轉化為標準形式。
例題2
將8個相同的小球放到3個不同的盒子,每個盒子至少放兩個球,一共有多少種方法。
解析:先往每一個盒子裡放一個小球。轉化為:5個相同的小球放到不同的盒子,每個盒子至少放1個小球,一共有多少種方法。$C_4^2=6$種。
例題3
將8個相同的小球放到3個不同的盒子,有多少種方法。
解析:我們先讓每個盒子吐出1個球,使得每個盒子至少一個球,分球的時候再讓盒子吃回去。轉化為:11個相同的球放到3個不同的盒子中,每個盒子至少一個,有多少種方法。$C_{10}^2=45$種。
例題4
$a+b+c=10$有多少組正整數解。
解析:轉化為:10個相同的小球,放到不同的3個盒子中,每個盒子至少一個,有多少方法。$C_9^2=36$種。
例題5
$a+b+c=10$有多少組非負整數解。
解析:轉化為:13個相同的小球,放到不同的3個盒子中,有多少方法。$C_{12}^2=66$種。
例題6
$a+b+c\leqslant 10$有多少組非負整數解。
解析1:轉化為$a+b+c+d =10$,即10個相同的球,放到4個不同的盒子中,有多少方法。$C_{13}^3=286$種。
解析2:列舉所有情況:$a+b+c=0(C_2^2)$,$a+b+c=1(C_3^2)$,$\cdots$,$a+b+c=10(C_{12}^2)$,$\sum\limits_{i=2}^{12}C_i^2=C_{13}^3=286$種。
注:$\sum\limits_{i=m}^nC_i^m=C_{n+1}^{m+1}$。
楊輝三角性質之一:斜線上數字的和等於其向左(從左上方到右下方的斜線)或向右拐彎(從右上方到左下方的斜線),拐角上的數字。