[组合记录] 容斥原理

https://renamoe.gitee.io/2021/04/08/容斥原理学习笔记/

[ZJOI2016]小星星

\(f[i][j][S]\) 表示树上点 \(i\),编号成 \(j\),子树内已经有的编号集合为 \(S\)。暴力转移复杂度带个枚举子集。

考虑去掉 \(S\) 的限制,\(S\) 的限制就是 \(S = 2^n - 1\) 其中每个数必须用至多一次。

如果只设 \(f[i][j]\) 的话,就是有可能有编号重复利用。这里就是可以容斥。

钦定一个集合 \(S\),dp 时保证所有编号是 \(S\) 的子集。

那么答案就是 \(ans(|S| = n) - ans(|S| = n - 1) + ans(|S| = n - 2) - \dots\)

容斥系数 \((-1)^{n - |S|}\)

summary:先写出朴素 dp,考虑限制因素 要求编号不重不漏。对着这个容斥。

[SHOI2016]黑暗前的幻想乡

与上一题类似。考虑限制:\(n - 1\) 个公司各处理一条不同的边。

如果只用一次矩阵树定理,会得到恰好由 \(n - 1\) 个公司组成的方案。

但是,也会多算恰为 \(n - 2\) 个公司组成的方案

于是钦定集合 \(S\),矩阵树定理只加入 \(S\) 中的边。

\(ans(|S| = n - 1) - ans(|S| = n - 2) + ans(|S| = n - 3) - \dots\)

记得当初写的时候,有些人用了 \(determinant\) 的一些性质。

summary:与上题类似。

【UR #5】怎样跑得更快

考虑

\[\sum_{j=1}^{n} \gcd(i,j) ^ {c - d} i^d j^d x_j \equiv b_i \]

显然 i, j 随意,即求

\[\sum_{j=1}^{n} {\gcd(i,j)}^k x_j \equiv b_i \]

完事后除一除。。。

\(f(\gcd(i,j)) = \gcd^k(i,j)\),试图寻找 \(f(n) = \sum_{d|n} f_r(d)\)

那么

\[\sum_{j=1}^{n} \sum_{d|i,d|j} f_r(d) x_j = b_i \]

\[\sum_{d|i}\sum_{d|j} f_r(d) x_j \equiv b_i \]

然后发现三个莫反完事了。

trick!!!

\(f(n) = \sum_{d|n} g(d)\)

\(f(n) = \sum_{n|d} g(d)\)

已知 \(f\)\(g\)。原理是移项。

点击查看代码
void f_mu(int *f) {
	for(int i = 1; i <= n; ++ i) 
		for(int j = i + i; j <= n; j += i) {
			f[j] = (f[j] + P - f[i]);
			if(f[j] >= P) f[j] -= P;
		}
}
void f_mu_re(int *f) {
	for(int i = n; i >= 1; -- i) {
		for(int j = i + i; j <= n; j += i) {
			f[i] = ( f[i] + P - f[j] );
			if(f[i] >= P) f[i] -= P;
		}
	}
}

summary : 板子题。无话可说。

posted @ 2023-03-13 17:32  Lates  阅读(18)  评论(0编辑  收藏  举报