算法数学笔记-四、组合数学

时间:2022-09-29
本文章向大家介绍算法数学笔记-四、组合数学,主要内容包括四、组合数学、Prufer序列、二项式反演、单位根反演、min-max容斥、卡特兰数、斯特林数、斯特林反演、贝尔数、使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

四、组合数学

Prufer序列

long long fa[N], prufer[N], d[N];
long long n, m, ans;

void get_Prufer(){
	
	long long p = 1, tot = 0;
	for(long long i = 1; i <= n - 1; i ++)
		d[fa[i]] ++, d[i] ++;
		
	for(long long i = 1, p = 1; i <= n; p = ++ i)
		while(d[p] == 1 && p <= i && tot + 1 <= n - 2)
			prufer[++ tot] = fa[p], d[fa[p]] --, p = fa[p];
	
	return ;
}

void get_Tree(){
	
	long long root = n;
	for(long long i = 1; i <= n - 2; i ++)
		d[prufer[i]] ++;
	for(long long i = 1; i <= n; i ++)
		d[i] ++, fa[i] = root;
	
	long long cnt = 0;
	for(long long i = 1, p = 1; i <= n; p = ++ i)
		while(d[p] == 1 && p <= i && cnt + 1 <= n - 2)
			fa[p] = prufer[++ cnt], d[prufer[cnt]] --, p = fa[p];
	
}

二项式反演

\[F(n) = \sum_{i=0}^n{(-1)^i {{n}\choose i}} G(i) \ \ ⟺ \ \ G(n) = \sum_{i=0}^n{(-1)^i {{n}\choose i}} F(i) \\ F(n) = \sum_{i=0}^n{{{n}\choose i}} G(i) \ \ ⟺ \ \ G(n) = \sum_{i=0}^n{(-1)^{i-n} {{n}\choose i}} F(i) \\ F(n) = \sum_{i=n} {(-1)^i {{i}\choose n}} G(i) \ \ ⟺ \ \ G(n) = \sum_{i=n} {(-1)^i {{i}\choose n}} F(i) \\ F(n) = \sum_{i=n} {{{i}\choose n}} G(i) \ \ ⟺ \ \ G(n) = \sum_{i=n} {(-1)^{i-n} {{i}\choose n}} F(i) \]

单位根反演

\[[n|a]\ = \ {\frac{1}{n} \sum_{k = 0} ^{n -1} w^{ak}_n} \\ [a=b \ ( \% n)] = [a - b = 0 \ (\% n)] = {\frac{1}{n} \sum_{k = 0} ^{n -1} w^{(a-b)k}_n} = {\frac{1}{n} \sum_{k = 0} ^{n -1} w^{ak}_nw_n^{-bk}} \]

\(w_n^k\)\(x^n=1\)的第k个复数解,等于\(w_n\)的k次方

min-max容斥

\[max(S) =\sum_{T \subseteq S}) ^ {|T| + 1}min(T) \\ min(S) =\sum_{T \subseteq S}) ^ {|T| + 1}max(T) \\ E(max(S)) =\sum_{T \subseteq S}) ^ {|T| + 1}E(min(T)) \\ E(min(S)) =\sum_{T \subseteq S}) ^ {|T| + 1}E(max(T)) \]

卡特兰数

\(Cat_n = \frac{C^n_{2n}}{n + 1}\)

\(Cat_1 = 1, Cat_n = Cat_{n - 1} \frac{4n-2}{n + 1}\)

斯特林数

第二类斯特林数·列

poly::vec ask[N << 1];

void part(int p, int l, int r){
	if(l == r){
		ask[p].resize(2);
		ask[p][0] = 1;
		ask[p][1] = mod - l;
		return ;	
	}
	
	int mid = l + r >> 1;
	
	part(p << 1, l, mid);
	part(p << 1 | 1, mid + 1, r);
	
	ask[p] = poly::Multiply(ask[p << 1], ask[p << 1 | 1]);
}

void work(){
	
	using namespace poly;
	
	int n, k;
	cin >> n >> k;
	part(1, 1, k);
	
	ask[1] = GetInv(n + 1, ask[1]);
	for(int i = 0; i <= k - 1; i ++)
		printf("0 ");
	
	for(int i = k; i <= n; i ++)
		printf("%d ", ask[1][i - k]);
}
\[H(n) = \frac{x^n}{\prod_i(1 - ix)} \\ \sum_{n = k} ^ \infty S_2(n, k) \frac{x^n}{n!} = \frac {(e^x - 1)^k}{k!} \]

第二类斯特林数·列

\[S_2(n, m) = \sum _{i = 0} ^m \frac{i^n}{i!} \frac{(-1)^{m - i}}{(m - i)!} \]

第一类斯特林数

\[S_1 (n, m) = S_1(n - 1, m - 1) + (n - 1)S_1(n - 1, m) \]

\(S_1(n, i)\)的生成函数

\[\sum _{i = 0}^{n - 1} (s +i) \]

分治+NTT\(O(nlognlogn)\)

斯特林反演

\[f(n) = \sum_{i = 0}^n S_2(n, i)g(i) \ \\ \\ g(n) = \sum_{i = 0}^n(-1)^{n - i} S_1(n,i)f(i) \]

贝尔数

\[B_{n + 1} = \sum^n_{k = 0} {n \choose k} B_k \\ B_{p + n} \equiv B_n + B_{n + 1} (mod\ p) \ \ (p\ is\ a\ prime) \\ \\ \sum _{n = 0} ^ \infty \frac{B_n}{n!} x^n = e^{e^x -1} \]

拆分数

把{1,2,3......n} 分成S = {1,2......T}和B = {T+1,T+2......n};

\[Ans = \sum_{i=0}^n ans_S[i] * ans_T[n - i] \]

对于S:\(dp_{i,j}\)表示组成i最大为j的方案数

\(dp_{i,j} \ =\ \sum _{k = 0} ^ j dp_{i-j,k}\ = \ \sum_{k=0} ^ {j-1}dp_{i-j,k} + dp_{i-j,j} \ = \ dp_{i-1,j-1} + dp_{i-j,j}\)

对于T:\(dp_{i,j}\)表示组成i用了j个数的方案数

\(dp_{i,j} = dp_{i-T-1,j - 1} + dp_{i-j,j}\)

\(dp_{i-T-1,j - 1}\):i中最小的数为(T+1)

\(dp_{i-j,j}\): i中最小的数不为T+1,将这j个数-1

欧拉数

\[Eular(n, k) = \sum _{x = k} ^n (-1)^{n - x}(x - k) ^ n \frac{(n + 1) ! }{(x + 1) ! (n - x)!} \]

\(n^2的dp:\) dp[i][j]: i 的排列中,有j个小于号的方案数

\[dp[i][0] = 1 \\ dp[i][j] \ =\ dp[i - 1][j - 1] * (i - j) + dp[i - 1][j] * (j + 1) \]

常用生成函数

卡特兰生成函数

\[C(x) = \frac{ \sqrt{1 - 4x}}{2x} = \sum^{\infty}_{i=0} {\frac{2i \choose i}{i+1}}x^i \]

斐波拉契生成函数

\[F(x) = xF(x) + x^2F(x) - f_0x + f_1x + f_0 \\ \\ F(x) = \frac{x}{1 - x - x^2} \]

欧拉变换

\[Eular(F(x)) = \prod_i \frac{1}{(1 - x^i) ^{f_i}} \]

类似于EGF中的exp变换

\[exp(F(x)) = \sum_i \frac{F^i(x)}{i!} \]

EGF 的\(exp\)具有的组合意义是:将\(1\sim n\)分成若干非空组,大小为 的\(f_i\)组内部具有 中方\(f_i\)案,问最后的总方案数。

而 Euler 变换就是去除了这个标号的方案数,去掉标号会导致「如果两个组大小和内部方案均相同,则它们不可区分」。

因此 \text{Euler}Euler 的第一个定义式就易懂了。(即大小为 ii 的每种内部方案都可以选若干个,每种内部方案的生成函数都是\((1 - x^i) ^{-1}\)

现在有两种方法可以得到Euler 变换的第二个定义式:

\[Eular(F(x)) = exp(\sum_i \ln \frac{1}{(1 - x^i)^{f_i}}) \\ = exp(\sum_i - f_i \ln (1 - x^i)) \\ = exp(\sum_i f_i\sum_j \frac{x^{ij}}{j}) \\ = exp(\sum _j \frac{F(x^j)}{j}) \]

原文地址:https://www.cnblogs.com/lyhy/p/16743081.html