1. 程式人生 > 實用技巧 >Lucas(盧卡斯)定理

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;
}

例題

HDU 3037

解析: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}$。

楊輝三角性質之一:斜線上數字的和等於其向左(從左上方到右下方的斜線)或向右拐彎(從右上方到左下方的斜線),拐角上的數字。