概念

Min-Max容斥,又称最值反演,是一种对于特定集合,在已知最小值或最大值中的一者情况下,求另一者的算法。

例如:

\[max(a,b)=a+b-min(a,b) \\ max(a,b,c)=a+b+c-min(a,b)-min(a,c)-min(b,c)+min(a,b,c)
\]

显然,将所有数取相反数,易知用最大值求最小值的公式与用最小值求最大值的公式形式相同。以下只讨论用最小值求最大值的方法。

形式

记 \(Max(S)\) 表示集合 \(S\) 的最大值,\(Min(S)\) 表示集合 \(S\) 的最小值,则:

\[Max(S)=\sum\limits_{T\subset S,T\neq \phi}(-1)^{|T|-1}Min(T)
\]

推导

设存在一个以集合大小为自变量的函数 \(f\) 满足 \(Max(S)=\sum\limits_{T\subset S,T\neq \phi}f(|T|)Min(T)\) 。

记 \(S\) 中元素从大到小排列为 \(x_1,x_2,...,x_m\) ,则对于 \(x_i\) ,其在左侧的贡献为 \([i=1]\) ,在右侧的贡献为 \(\sum\limits_{j=0}^{i-1}{i-1\choose j}f(j+1)\) 。

若等式成立,则必有 \([i=1]=\sum\limits_{j=0}^{i-1}{i-1\choose j}f(j+1)\) 。

设 \(F(i)=[i+1=1]\) (即 \([i=1]=F(i-1)\) ),\(G(i)=f(i+1)\) ,则 \(F(i)=\sum\limits_{j=0}^{i}{i\choose j}G(j)\) 。

进行二项式反演,得 \(G(i)=\sum\limits_{j=0}^{i}(-1)^{i-j}{i\choose j}F(j)=(-1)^i\) 。

故 \(f(i)=G(i-1)=(-1)^{i-1}\) 。

因此构造成立,故:

\[Max(S)=\sum\limits_{T\subset S,T\neq \phi}(-1)^{|T|-1}Min(T)
\]

另一种证明

考虑等式右侧,记最小值为 \(x_i\) ,则:

  • 当 \(i=1\) 时,贡献为 \(1\) ;
  • 当 \(i\neq 1\) 时,则 \(x_1\) 有选和不选两种方案,这两种方案一一对应且系数恰为相反数,故总贡献为 \(0\) 。

故右侧的总和就是 \(x_1=Max(S)\) 。

推广

记 \(kMax(S)\) 表示集合 \(S\) 的第 \(k\) 大值,则:

\[kMax(S)=\sum\limits_{T\subset S,|T|\ge k}(-1)^{|T|-k}{|T|-1\choose k-1}Min(T)
\]

推导

设存在一个以集合大小为自变量的函数 \(g\) 满足 \(kMax(S)=\sum\limits_{T\subset S,T\neq \phi}g(|T|)Min(T)\) 。

记 \(S\) 中元素从大到小排列为 \(x_1,x_2,...,x_m\) ,则对于 \(x_i\) ,其在左侧的贡献为 \([i=k]\) ,在右侧的贡献为 \(\sum\limits_{j=0}^{i-1}{i-1\choose j}g(j+1)\) 。

若等式成立,则必有 \([i=k]=\sum\limits_{j=0}^{i-1}{i-1\choose j}g(j+1)\) 。

设 \(F(i)=[i+1=k]\) (即 \([i=k]=F(i-1)\) ),\(G(i)=g(i+1)\) ,则 \(F(i)=\sum\limits_{j=0}^{i}{i\choose j}G(j)\) 。

进行二项式反演,得 \(G(i)=\sum\limits_{j=0}^{i}(-1)^{i-j}{i\choose j}F(j)=(-1)^{i-k+1}{i\choose k-1}\) 。

故 \(f(i)=G(i-1)=(-1)^{i-k}{i-1\choose k-1}\) 。

因此构造成立,故:

\[kMax(S)=\sum\limits_{T\subset S,|T|\ge k}(-1)^{|T|-k}{|T|-1\choose k-1}Min(T)
\]

应用

Min-Max容斥及其推广常用于解决“都出现的期望时间”问题,处理方法:

记 \(t_i\) 表示第 \(i\) 个元素的出现时间,则:

  • \(Max(S)\) 表示 \(S\) 中 \(t\) 的最大值,即所有元素出现时间的最大值,即所有元素都出现的时间;
  • \(Min(S)\) 表示 \(S\) 中 \(t\) 的最小值,即所有元素出现时间的最小值,即至少有一个出现的时间。

根据Min-Max容斥,有 \(Max(S)=\sum\limits_{T\subset S,T\neq \phi}(-1)^{|T|-1}Min(T)\) 。

对左右同时取期望,由于线性,期望可以直接放到求和符号里面,即 \(E(Max(S))=\sum\limits_{T\subset S,T\neq \phi}(-1)^{|T|-1}E(Min(T))\) 。

容易发现 \(E(Min(T))\) 求起来十分容易:当单位时间出现 \(T\) 中至少一个的概率为 \(p\) ,则出现 \(T\) 中至少一个的期望时间为 \(\frac 1p\) 。

于是通过公式即可求出 \(Max(S)\) ,即所有元素都出现的期望时间。

对于Min-kMax容斥同理。

写法

如果只需要求出 \(Max(U)\) ,即全集的最大值的话,只需要计算每个自己对全集的贡献即可。

如果要对所有 \(S\) 求 \(Max(S)\) 的话(尽管似乎还没遇到过),一种较快的方法是用按位分治来代替枚举子集。有两种常用写法,它们稍加处理就可以变成公式中的形式。

写法一

for(i = 1 ; i < (1 << n) ; i <<= 1)
for(j = 0 ; j < (1 << n) ; j ++ )
if(j & i)
f[j] -= f[i];

此时系数是 \((-1)^{|S|-|T}\) .

写法二

for(i = 1 ; i < (1 << n) ; i <<= 1)
for(j = 0 ; j < (1 << n) ; j ++ )
if(j & i)
f[j] = f[i] - f[j];

此时系数是 \((-1)^{|T|}\) 。

例题

[hdu4336]Card Collector

题目大意

有 \(n\) 种卡片,每次购买有 \(p_i\) 的概率买到第 \(i\) 种,求使得每种都买到的期望购买次数。

\(1\le n\le 20\) 。

题解

Min-Max容斥基础题,参见上面的 “应用” 部分。

对于本题,有 \(Min(S)=\frac 1{\sum\limits_{i\in S}p_i}\) ,然后套用 \(Min-Max\) 容斥的公式即可。

时间复杂度 \(O(2^n)\) 。

#include <cstdio>
#define N 1100010
int cnt[N];
double p[N] , f[N];
int main()
{
int n , i , j;
double ans;
while(~scanf("%d" , &n))
{
ans = 0;
for(i = 0 ; i < n ; i ++ ) scanf("%lf" , &p[1 << i]);
for(i = 1 ; i < (1 << n) ; i ++ ) f[i] = f[i - (i & (-i))] + p[i & (-i)] , cnt[i] = cnt[i - (i & -i)] + 1;
for(i = 1 ; i < (1 << n) ; i ++ ) ans += ((cnt[i] & 1) ? 1 : -1) / f[i];
printf("%lf\n" , ans);
}
return 0;
}

[bzoj4036]按位或

题目大意

你初始有数字 \(0\) ,每次操作会随机选择 \([0,2^n-1]\) 的一个数字与你的数字进行按位或运算,选到数 \(i\) 的概率为 \(p_i\) 。求使得你的数字变为 \(2^n-1\) 的期望操作次数。

\(1\le n\le 20\) 。

题解

和上一题类似,问题转化为计算 \(Min(S)\) ,即需要求出所有与 \(S\) 有公共元素(取与不为 \(0\) )的 \(p\) 之和。

正难则反,考虑求所有与 \(S\) 无公共元素的 \(p\) 之和,即 \(S\) 的补集 \(2^n-1-S\) 的所有子集的 \(p\) 之和,使用按位分治来解决。

最后套公式计算即可。无解的判定通过判断是否某一位都存在一个 \(p\neq 0\) 的元素来处理。

时间复杂度 \(O(n\times 2^n)\) 。

代码

#include <cstdio>
#include <algorithm>
using namespace std;
double p[1100010];
int cnt[1100010];
int main()
{
int n , i , j;
double ans = 0;
scanf("%d" , &n);
for(i = 0 ; i < (1 << n) ; i ++ ) scanf("%lf" , &p[i]);
for(i = 1 ; i < (1 << n) ; i ++ ) cnt[i] = cnt[i - (i & -i)] + 1;
for(i = 1 ; i < (1 << n) ; i <<= 1)
{
for(j = 0 ; j < (1 << n) ; j ++ )
if((j & i) && p[j])
break;
if(j == (1 << n))
{
puts("INF");
return 0;
}
}
for(i = 1 ; i < (1 << n) ; i <<= 1)
for(j = 0 ; j < (1 << n) ; j ++ )
if(j & i)
p[j] += p[j ^ i];
for(i = 1 ; i < (1 << n) ; i ++ ) ans += ((cnt[i] & 1) ? 1 : -1) / (1 - p[(1 << n) - 1 - i]);
printf("%.8lf\n" , ans);
return 0;
}

[luogu4707]重返现世

题目大意

有 \(n\) 种物质,每单位时间会随机生成一种物质,生成第 \(i\) 种物质的概率为 \(\frac{p_i}m\) 。求获得 \(k\) 种物质的期望时间。

\(1\le n\le 1000\) ,\(1\le m\le 10000\) ,\(1\le k\le n\) ,\(p_i\) 为整数且 \(\sum\limits_{i=1}^np_i=m\) ,\(n-k\le 10\) 。

题解

获得 \(k\) 种物质,相当于求所有获得时间中第 \(n-k+1\) 大的,问题转化为Min-kMax容斥问题。方便起见,以下令 \(q=n-k+1\) ,则有 \(1\le q\le 11\) 。

由于 \(n\) 有 \(1000\) 之大,使用前两道题的子集统计方法显然会直接暴毙。

思考:尽管我们的集合选取方案有 \(2^n\) 种,但每种的 \(Min(S)\) 只和 \(\sum\limits_{i\in S}p_i\) 有关,因此状态数其实只有 \(m\) 种。

一个比较显然的思路是设 \(f_{i,j,l}\) 表示前 \(i\) 种物质选出 \(j\) 种,凑齐 \(\sum p=l\) 的方案数,然而数据范围过大,无法通过此题。

到此为止,我们还有一个条件没有用到:\(q\le 11\) 。

考虑在已知 \(f_{i,j,l}\) 后答案的计算,贡献为 \((-1)^{j-q}{j-1\choose q-1}\times \frac ml\times f_{i,j,l}\) 。对于前面的部分,运用组合数公式,有:

\[(-1)^{j-q}{j-1\choose q-1}=(-1)^{(j-1)-(q-1)}{j-2\choose q-2}-(-1)^{(j-1)-q}{j-2\choose q-1}
\]

而 \(f_{i,j,l}\) 又有转移 \(f_{i,j,l}=f_{i-1,j,l}+f_{i-1,j-1,l-p_i}\) ,故:

\[(-1)^{j-q}{j-1\choose q-1}f_{i,j,l}=(-1)^{j-q}{j-1\choose q-1}f_{i-1,j,l}+(-1)^{(j-1)-(q-1)}{j-2\choose q-2}f_{i-1,j-1,l-p_i}-(-1)^{(j-1)-q}{j-2\choose q-1}f_{i-1,j-1,l-p_i}
\]

发现了什么?前面的系数只和 \(j\) 与计算答案时所用的 \(q\) 有关,因此设 \(g_{i,j,l,t}\) 表示前 \(i\) 种物质选出 \(j\) 种,凑齐 \(\sum p=l\) ,且最终计算时的 \(q=t\) 的系数乘以方案数。则有:

\[g_{i,j,l,t}=g_{i-1,j,l,t}+g_{i-1,j-1,l-p_i,t-1}-g_{i-1,j-1,l-p_i,t}
\]

我们所做的似乎都是无用功。但事实上,仔细观察就会发现 \(j\) 的一维已经没有用处,无论是转移还是最终答案都不需要用到 \(j\)。

左右对 \(j\) 那一维求和,便有 \(h_{i,l,t}\) 表示前 \(i\) 种物质选出若干种,凑齐 \(\sum p=l\) ,且最终计算时的 \(q=t\) 的系数乘以方案数,则有:

\[h_{i,l,t}=h_{i-1,l,t}+h_{i-1,l-p_i,t-1}-h_{i-1,l-p_i,t}
\]

最终答案就是 \(\sum\limits_{i=1}^mh_{n,i,q}\times \frac mi\) 。

时间复杂度 \(O(nmq)\) ,由于空间不足,需要使用滚动数组。

代码

#include <cstdio>
#include <cstring>
#define mod 998244353
typedef long long ll;
ll p[1010] , f[2][10010][11];
inline ll qpow(ll x , ll y)
{
ll ans = 1;
while(y)
{
if(y & 1) ans = ans * x % mod;
x = x * x % mod , y >>= 1;
}
return ans;
}
int main()
{
int n , t , m , i , j , k , d;
ll ans = 0;
scanf("%d%d%d" , &n , &t , &m) , t = n - t + 1;
for(i = 1 ; i <= n ; i ++ ) scanf("%lld" , &p[i]);
for(i = 1 ; i <= t ; i ++ ) f[0][0][i] = -1;
for(d = i = 1 ; i <= n ; i ++ , d ^= 1)
{
memcpy(f[d] , f[d ^ 1] , sizeof(f[d]));
for(j = p[i] ; j <= m ; j ++ )
for(k = 1 ; k <= t ; k ++ )
f[d][j][k] = (f[d][j][k] + f[d ^ 1][j - p[i]][k - 1] - f[d ^ 1][j - p[i]][k] + mod) % mod;
}
for(i = 1 ; i <= m ; i ++ ) ans = (ans + f[n & 1][i][t] * m % mod * qpow(i , mod - 2)) % mod;
printf("%lld\n" , ans);
return 0;
}

Min-Max容斥及其推广和应用的更多相关文章

  1. min-max 容斥

    $\min - \max$ 容斥 Part 1 对于简单的$\min - \max$容斥有一般形式,表达为:$\max(S)=\sum\limits_{T\subseteq S}(-1)^{|T|-1 ...

  2. Min-max 容斥与 kth 容斥

    期望的线性性: \[E(x+y)=E(x)+E(y) \] 证明: \[E(x+y)=\sum_i \sum_j(i+j)*P(i=x,j=y) \] \[=\sum_i\sum_ji*P(i=x,j ...

  3. min-max容斥学习笔记

    min-max容斥学习笔记 前置知识 二项式反演 \[ f(n)=\sum_{i=0}^n\binom{n}{i}g(i)\Leftrightarrow g(n)=\sum_{i=0}^n(-1)^{ ...

  4. [学习笔记]min-max容斥

    [Learning]min-max容斥以及推广 min-max容斥 就是max(a,b)=min(a)+min(b)-min(a,b) max(a,b,c)=a+b+c-min(a,b)-min(a, ...

  5. [模板] 容斥原理: 二项式反演 / Stirling 反演 / min-max 容斥 / 子集反演 / 莫比乌斯反演

    //待更qwq 反演原理 二项式反演 若 \[g_i=\sum_{j=1}^i {\binom ij} f_j\] , 则有 \[ f_i=\sum_{j=1}^i (-1)^{i-j} {i \ch ...

  6. [总结] Min-Max容斥学习笔记

    min-max 容斥 给定集合 \(S\) ,设 \(\max(S)\) 为 \(S\) 中的最大值,\(\min(S)\) 为 \(S\) 中的最小值,则: \[\max(S)=\sum_{T\in ...

  7. MinMax 容斥 学习笔记

    基本形式 \[ \max(S) = \sum_{T\subseteq S, T \neq \varnothing} (-1)^{|T|-1}\min(T) \] 证明 不提供数学证明. 简要讲一下抽象 ...

  8. HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

    题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...

  9. UVa12633 Super Rooks on Chessboard(容斥 + FFT)

    题目 Source http://acm.hust.edu.cn/vjudge/problem/42145 Description Let’s assume there is a new chess ...

随机推荐

  1. Mysql 行锁 for update

    Mysql 只有Innodb支持行锁 使用行锁需要 事务支持 首先打开两个 mysql-client 分别执行 - client1 select * from my_entity1 for updat ...

  2. Gradle 知识点

    mac 系统中,下载的 Gradle 压缩包解压后存储的文件夹:/Users//.gradle/wrapper/dists 当Gradle运行时,会根据settings.gradle的配置情况,构建一 ...

  3. 21、numpy数组模块

    一.numpy简介 numpy官方文档:https://docs.scipy.org/doc/numpy/reference/?v=20190307135750 numpy是Python的一种开源的数 ...

  4. python文件读取,替换(带格式,python lib 库)

    import os, time import sys import re def read_old_part(filename, start, end): content = [] recording ...

  5. 【转载】TCP协议

    首部格式 图释: 各个段位说明: 源端口和目的端口:各占 2 字节.端口是传输层与应用层的服务接口.传输层的复用和分用功能都要通过端口才能实现 序号:占 4 字节.TCP 连接中传送的数据流中的每一个 ...

  6. React Virtual DOM Explained in Simple English

    If you are using React or learning React, you must have heard of the term “Virtual DOM”. Now what is ...

  7. vue分组全选权限,CheckBoxGroup

    <template> <div class="comPower"> <div class="card_header" v-show ...

  8. prisma2 预览版

    prisma2 预览版已经发布好几个版本了,同时官方的参考文档也在github 可以看到 新版本的架构变动 参考图 说明 photon 为一个类型安全的数据库客户端(替换orm) lift 数据模型的 ...

  9. 怎么把ubuntu升级到最新版本

    首先是Ctrl+Alt+T 打开终端,然后在终端中输入指令(更新资源) sudo apt-get update 接着是对软件进行升级.(这是一个漫长的过程,需要下载资源) sudo apt-get u ...

  10. FDQuery Out of memory

    4万行记录 FDQuery查询 Out of memory sql server 可以查询成功 First chance exception at $7505D722. Exception class ...