容斥

二项式定理

\[(a + b) ^ n = \sum_{i=0}^n \binom{n}{i} \cdot a ^ {i} \cdot b ^ {n - i} \]

证明:

\(n\)\((a + b)\), 考虑对于最终 \(a ^ k \cdot b ^ {n - k}\) 的贡献:
每一项选 \(a\)\(b\) 然后相乘累加, 那么总共从 \(n\) 项里选 \(k\)\(a\), 其余都选 \(b\)

常见带入:

\[(x + 1) ^ n = \sum_{i=0}^n \binom{n}{i} x ^ i \]

\[(1 + x) ^ n = \sum_{i=0}^n \binom{n}{i} x ^ {n - i} \]

\[(x + 1) ^ n = \sum_{i=0}^n \binom{n}{n - i} x ^ {n - i} \]

二项式反演

\[f_n = \sum_{i=0}^n (-1)^i {n \choose i} g_i \Leftrightarrow g_n = \sum_{i=0}^n (-1)^i {n \choose i} f_i \]

下面这个式子的 \(g(i)\) 当做上面的 \(g(i) \cdot (-1) ^ i\), 然后带入易得

\[f_n = \sum_{i=0}^n {n \choose i} g_i \Leftrightarrow g_n = \sum_{i=0}^n (-1)^{n-i} {n \choose i} f_i \]

证明第一个:

充要条件, 那么左边可推出右边, 右边可推出左边

由于这两个式子对称, 这里就偷懒只证明一个方向好了
例: 充分性: 左 \(\Rightarrow\)

\[\begin{aligned} g_n & = \sum_{i=0}^n (-1)^i \binom{n}{i} \sum_{j=0}^i (-1)^j \binom{i}{j} g_j \\ & = \sum_{i=0}^n \sum_{j=0}^i (-1)^{i + j} \binom{n}{i} \binom{i}{j} g_j \end{aligned} \]

写在一个矩阵里比较直观(对于推导不是必要的), 观察右下角即为 \(g_n\) 与等式左边相同, 若要成立说明前面一片是 \(0\):

\[\begin{bmatrix} & \binom{n}{0}\binom{0}{0} g_0 \\ & -\binom{n}{1}\binom{1}{0} g_0 & \binom{n}{1}\binom{1}{1} g_1 \\ & \binom{n}{2}\binom{2}{0} g_0 & -\binom{n}{2}\binom{2}{1} g_1 & \binom{n}{2}\binom{2}{2} g_2\\ & \vdots & \vdots & \ddots & \\ & (-1)^n\binom{n}{n}\binom{n}{0} g_0 & (-1)^{n+1}\binom{n}{n}\binom{n}{1} g_1 & \dots & (-1)^{2n}\binom{n}{n}\binom{n}{n} g_n\\ \end{bmatrix} \]

改成竖向求和

\[\begin{aligned} g_n & = \sum_{i=0}^n g_i \sum_{j=i}^n \binom{n}{i} \binom{i}{j} (-1)^{i+j}\\ & = \sum_{i=0}^n g_i \binom{n}{j} \sum_{j=i}^n \binom{n-i}{j-i} (-1) ^ {i + j} \end{aligned} \]

解释一下组合数: \(i \in j \in n\), 画一个集合图可得
然后最后面一段像是二项式定理, 把 \(j\) 换元成原来的 \(j-i\) 比较直观 (换元可以参考上面的矩阵的规律)

\[\begin{aligned} g_n & = \sum_{i=0}^n g_i \binom{n}{j} \sum_{j=0}^{n - i} \binom{n-i}{j} (-1) ^ {j} \\ & = \sum_{i=0}^n g_i \binom{n}{j} (-1 + 1) ^ {n-i} \\ & = \sum_{i=0}^n g_i \binom{n}{j} [i = n] \\ & = g_n \end{aligned} \]

min-max 容斥

\(\max(S), \min(S)\) 分别表示 \(S\) 中的最大,最小元素

那么有这样两个式子:

\[\begin{cases} \max(S) & = \sum_{T \subseteq S} (-1) ^ {|T| - 1} \min(T) \\ \min(T) & = \sum_{T \subseteq S} (-1) ^ {|T| - 1} \max(T) \\ \end{cases} \]

证明:

第一个:

将元素从大到小排序 \(\{a_1, a_2, \dots, a_n\}\), 当 \(a_{x + 1}\) 作为 \(\min(T)\) 时,
他的系数是 \(\sum_{i=0}^x \binom{x}{i} (-1) ^ {i + 1 - 1}\) , 这是 \((-1 + 1) ^ x\) 的二项式展开,
那么当 \(x = 0\) 时系数为 \(1\) 否则为 \(0\), 即 \(\max(S) = \min(\{ a_1 \})\)

第二个:
从小到大排序, 其余一样

kth min-max 容斥

\(\max_{k}(S), \min_{k}(S)\) 分别为 \(S\) 中第 \(k\) 大/小 的元素
\(\max_k(S) = \sum_{T \subseteq S} F(|T|) \min(T)\), 求得这个系数 \(F(|T|)\)

模仿上面的套路, 尝试用 \(\min(T)\) 来表示 \(\max_{k}(S)\) (\(\min_{k}(S)\) 同理)
将元素从大到小排序 \(\{a_1, a_2, \dots, a_n\}\), 当 \(a_{x + 1}\) 作为 \(\min(T)\) 时,
使得当 \(x = k - 1\) 时系数为 \(1\) 否则为 \(0\)

根据上面的关系可得 \(\sum_{i=0}^x \binom{x}{i} \cdot F(i + 1) = [x = (k - 1)]\)

套用二项式反演 \(f(i) = F(i + 1), g(i) = [i = (k - 1)]\)

\[\sum_{i=0}^x \binom{x}{i} \cdot F(i + 1) = [x = (k - 1)] \Leftrightarrow F(x + 1) = \sum_{i=0}^x (-1) ^ {x - i} \cdot \binom{x}{i} [i = (k - 1)] \]

\[F(x + 1) = (-1) ^ {x - (k - 1)} \cdot \binom{x}{k - 1} \]

所以

\[\max_{k}(S) = \sum_{T \subseteq S} (-1) ^ {|T| - k} \binom{|T| - 1}{k - 1} \min(T) \]

同理

\[\min_{k}(S) = \sum_{T \subseteq S} (-1) ^ {|T| - k} \binom{|T| - 1}{k - 1} \max(T) \]

例题

[HDU4336]Card Collector <min-max 容斥>

题意:
给出每种卡牌出现的概率(和为 1 , \(n \le 20\)), 每买一次按上述概率抽卡, 求买到所有卡的期望次数

Sol:
\(E(\max(S))\) 为买到 \(S\) 中剩下的最后一张卡的期望次数, 即答案(理解)
\(E(\min(S))\) 为买到 \(S\) 中第一张卡的期望次数, 显然是 \(\frac{1}{\sum_{i \in T} p_i}\)

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

预处理 + 枚举子集

typedef double LDB;

int n;

const int MAXN = (1 << 20) + 10;
int cnt[MAXN], d[MAXN];
LDB p[30], mnp[MAXN];

int lowbit(int x) { return x & (-x); } 

int main()
{
    while (scanf("%d", &n) != EOF)
    {
	d[1] = 0;
	for (int i = 1; i <= n; ++ i) 
	{
	    scanf("%lf", &p[i]);
	    d[1 << i] = i;
	}
	int S = (1 << n) - 1;
	mnp[0] = cnt[0] = 0;
	for (int i = 1; i <= S; ++ i)
	{
	    mnp[i] = mnp[i & (i - 1)] + p[d[lowbit(i)] + 1];
	    cnt[i] = cnt[i & (i - 1)] + 1;
	}
	LDB ans = 0;
	for (int T = S; T != 0; T = (T - 1) & S)
	    ans += (cnt[T] % 2 == 1 ? 1 : -1) * 1 / mnp[T];
	printf("%lf\n", ans);
    }
    return 0;
}

BZOJ4036: [HAOI2015]按位或

刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行或(c++,c的|,pascal
的or)操作。选择数字i的概率是p[i]。保证0<=p[i]<=1,Σp[i]=1问期望多少秒后,你手上的数字变成2^n-1。

Sol:

先套用 min-max, \(E(\max(S))\) 表示到达最后一个元素的期望, \(E(\min(S))\) 到达第一个元素的期望

考虑 \(E(\min(S))\) 怎么求, 当没有到达第一个元素的时候, 当前到达的集合和 \(S\) 是没有交集的, 这时需要或上一个与 \(S\) 有交集的数即可
于是发现既然没有到达之前都是无交集, 而且此时选择的数的概率仍然是这样, 那么无论何时概率都是 \(\sum_{t \cap S \ne \emptyset} p[t]\),
也就是说和上一题一样

在考虑如何快速求这个

\[E(\min(S)) = \sum_{t \cap S \ne \emptyset} p[t] \]

尝试转化成 FWT 能用的形式, 设 sum[S] = \(\sum_{t \cap S \ne \emptyset} p[t]\)

\[\begin{aligned} sum[S] & = totsum - \sum_{t \cap S = \emptyset} p[t] \\ & = totsum - \sum_{\complement t \cap S = S} p[t] \end{aligned} \]

后面那段就是 FWT and 的通式, 一遍 FWT 求得

void FWT(double * a, int len)
{
    // FWT(A) = merge(FWT(A0) + FWT(A1), FWT(A1)) ;
    for (int mid = 1; mid < len; mid <<= 1)
	for (int i = 0; i < len; i += (mid << 1))
	    for (int j = 0; j < mid; ++ j)
		a[i + j] += a[i + j + mid];
}

int main()
{
    n = in();
    int S = (1 << n) - 1;
    for (int i = 0; i <= S; ++ i) scanf("%lf", &p[i]), totsum += p[i];
    for (int i = 1; i <= S; ++ i)
    {
	int sub = i & (i - 1);
	cnt[i] = cnt[sub] + 1;
    }
    for (int i = 0; i <= S; ++ i)
	if (i < S - i) swap(p[i], p[S - i]);
    FWT(p, S + 1);
    double ans = 0;
    for (int T = S; T != 0; T = (T - 1) & S)
    {
	if (fabs(totsum - p[T]) <= 0) return printf("INF\n"), 0;
	ans += (cnt[T] % 2 == 1 ? 1 : -1) * 1.0 / (totsum - p[T]);
    }
    printf("%.6lf\n", ans);
    return 0;
}
posted @ 2019-12-17 09:30  Kuonji  阅读(207)  评论(0编辑  收藏  举报
nmdp