【NO COUNTINGs Plz!】

容斥原理

容斥原理的本质 不是 集合的并。容斥是从 DP 中自然得到的。

例题:树状图拓扑序计数。对于每条指向内的边,合法方案数 = 总方案数 - 不合法的方案数。所有点乘起来,系数就是 (-1)x 了。

例题。另一种理解:把贡献按照容斥系数线性组合起来,冗余的部分刚好抵消。

二项式反演

\(g(n)\):钦定 \(n\)\(f(n)\):恰好 \(n\)
\(g(n)=\sum \binom{n}{i}f(i)\)\(f(n)=\sum (-1)^{n-i}\binom{n}{i}g(i)\)

例题:求错排数。求在 2n 个子集中选出一些使得交为 i 的方案数。

数学期望

期望是什么?\(E=\sum pV\)

期望具有线性性。\(E(X+Y)=E(X)+E(Y)\)\(E(cX)=cE(X)\)

例题:绿豆蛙的归宿。本质上是利用了期望的线性性拆成概率再进行 DP。期望不能直接 DP,要转为概率 DP。

例题推式子小练习。暴力展开乘积式。

例题:Slime and Biscuits,求期望停时。如果我们能找到一个势能函数 \(\Phi\) 满足操作一次 \(E(\Delta\Phi)=-1\),最终答案就是 \(\Phi_0-\Phi_n\)

一些 tricks:\(E=\sum pV\),要先从这个考虑(P3600)。01 布尔变量的期望等于为 1 的概率。期望选中多少个点,可以转化为每个点被选中的概率之和(CF1924E)。一个随机排列 \(m\) 个钦定的数中一个数排在最前面的概率是 \(\dfrac{1}{m}\)(CF1924E)。若一个试验有 \(p\) 的概率成功,那么成功的期望重复次数为 \(\dfrac{1}{p}\)(CF1753C)。\(E(X)=\sum P(X\ge x)\),所以对于 \(\min,\max\) 的期望可以进一步拆为概率式(P3600,P3352)。

所以期望题怎么做?能拆就拆,拆不了了就用 \(\sum pV\) 算概率。

集合幂级数

OR 卷积:

点击查看代码
void OR(int *a) {
	for (int i = 0; i < n; i++) {
		for (int s = 0; s < (1 << n); s++)
			if (~s >> i & 1) a[s ^ (1 << i)] += a[s];
	}
}
void IOR(int *a) {
	for (int i = 0; i < n; i++)
		for (int s = 0; s < (1 << n); s++)
			if (~s >> i & 1) a[s ^ (1 << i)] -= a[s];   // 只是改了一个减号
}

XOR 卷积:
对于一个 \(S\)

\[\sum_T(-1)^{\operatorname{popcount}(S\&T)}c_T=\left[\sum_T(-1)^{\operatorname{popcount}(S\&T)}a_T\right]\left[\sum_T(-1)^{\operatorname{popcount}(S\&T)}b_T\right] \]

点击查看代码
void XOR(int *a) {
	for (int i = 0; i < n; i++) {
		for (int s = 0; s < (1 << n); s++) {
			if (~s >> i & 1) {
				int x = a[s], y = a[s ^ (1 << i)];
				a[s] = x + y; a[s ^ (1 << i)] = x - y;
			}
		}
	}
}
void IXOR(int *a) {
	for (int i = 0; i < n; i++) {
		for (int s = 0; s < (1 << n); s++) {
			if (~s >> i & 1) {
				int x = a[s], y = a[s ^ (1 << i)];
				a[s] = (x + y) / 2; a[s ^ (1 << i)] = (x - y) / 2;   // 只是多 / 2
			}
		}
	}
}
posted @ 2024-02-19 15:09  Network_Error  阅读(19)  评论(0)    收藏  举报