【反演】从一道例题出发探讨二项式反演、子集反演与容斥原理的关系
链接
给定 \(k\) 个特殊格子,求从 (1,1) 往右或往上走到 (n,m),在经过不超过 \(p\) 个特殊格的情况下的方案数
为了方便讨论,把 (1,1) 和 (n,m) 也看做特殊格。
设 \(f(S)\) 表示钦定至少走 S 集合中格子的方案,\(g(S)\) 为恰好走 S 集合的方案,那么 \(f\) 与 \(g\) 的关系就是一个 \(\subseteq\) 意义下的前缀和。即
\(f\) 用组合数很好求,为了求出每一个 \(g\),可以使用 \(O(3^k)\) 枚举子集,即
也可以把 \(g\to f\) 的过程看做高维前缀和,\(f\to g\) 就作一个\(O(k2^k)\)高维差分即可
这种形式的本质是子集反演,
可以用一般化的莫比乌斯反演理论,通过归纳法证明子集反演的莫比乌斯函数 \(\mu(A,B)=(-1)^{|B|-|A|}\)得到。
或者这么想,\(g(\empty)=\sum\limits_{T\sube U}(-1)^{|T|}f(T)\) 就是普通容斥原理,子集反演 \(g(S)\) 事实上可以理解为只考虑 \(S\) 的补集时的容斥原理。
严谨地说,定义 \(\bar{f}(S)=f(K\cup S)\),\(\bar{g}(S)=g(K\cup S)\),\(V=U\setminus K\),其中 \(U\) 是全集,\(\bar f\) 和 \(\bar g\) 的定义域都是 \(P(V)\)。
由
可得
令 \(T \to K\cup T\),
这就得到了子集反演的形式。
至此,我们得到结论,容斥是子集反演空集时的特殊情况,而子集反演则是考虑 \(U\) 的所有子集时的容斥。两者是可以相互推导的。
只不过本题要求所有 \(|S|\le p\) 的 \(f(S)\),用子集反演一个一个求 \(f\) 是 \(O(4^k)\),反而不优。
考虑 dp 状态 \(h_{i,j}\) 表示从 \((1,1)\) 到 \((x_i,y_i)\) 经过 \(j\) 次转移得到的方案数。(默认 p 是终点)
转移是
思考这里所谓”\(j\) 次转移“,实际上就是至少有 \(j\) 个特殊格,而且恰好有 \(w\) 格的方案数被算了 \(\binom{w}{j}\) 次。
于是终点处的 dp 值 \(h_{p,j}=F(j)=\sum_{k\ge j} G(k)\binom kj\),其中 \(G(n)\) 表示恰好走 \(n\) 个特殊点的方案。
得 \(G(j)=F(j)-\sum_{k>j}G(k)\binom kj\),倒序计算即可。复杂度 \(O(k^3)\)。
很明显 \(F\) 与 \(G\) 是二项式反演的关系。
把 \(h_{i,j}\) 进一步抽象,发现其本质就是经过了 \(j\) 个特殊点,且经过的最大特殊点为 \(i\) 的路径数。相对于指数做法,我们把记录的信息从具体经过了哪些点压缩到了经过的最大点是什么,从而将复杂度降低到多项式级别。
但我们知道其实 \(h\) 是算重了的。接下来,我们从另一个角度考虑 \(h\) 重数的规律。
我们要证明终点处 \(h_{p,n}\) 的每一个重数其实跟 \(\sum_{|S|=n}f(S)\) 一一对应。即证明 \(F(n)=h_{p,n}=\sum_{|S|=n}f(S)\)。
设 \(p=k_n\),\(r_{i,j}=\binom{(x_j-x_i)+(y_j-y_i)}{x_j-x_i}\),
也就是说,\(h_{p,n}\) 就是一些 \(r\) 乘积的和,而一串 \(r\) 的乘积其实就是 \(f\) 的计算方式。这样就从 dp 本身的角度找到了 \(F\) 与 \(f\) 之间的关系。其实本质上,dp 就是帮我们把指数级别的 \(f\) ,通过 \(\sum_{|S|=n}f(S)\) 压缩成了多项式级别的 \(F\)。
又由 \(G\) 和 \(g\) 的定义,显然有 \(G(n)=\sum_{|S|=n}g(S)\),再加上 \(f\) 与 \(g\) 满足的子集反演的式子,我们就可以推导出 \(F\) 与 \(G\) 满足的二项式反演的式子。
由
得
这与我们先前讨论的 \(F\) 和 \(G\) 的组合意义一致。
类似地由
可得
即
于是我们可以在 \(O(k)\) 的复杂度内由 \(F\) 求单个 \(G\)。
考虑有没有办法在 dp 过程中就把重数去掉。
之前 dp 产生重数的原因是:利用组合数计算两个特殊格之间的方案数时无法保证不再经过其他特殊格。
类似之前枚举子集去重的思想,设 \(w_{i,j}\) 表示第 \(i\) 个特殊格到第 \(j\) 个特殊格之间不经过其他特殊格的方案,\(r_{i,j}=\binom{(x_j-x_i)+(y_j-y_i)}{x_j-x_i}\) 表示没有不经过其他特殊格的限制。(注意这里特殊格要按照字典序排序,保证任意满足偏序关系的两个特殊格一定是小的在大的前面。)
如何用 \(r\) 算 \(w\)?考虑要从 \(r\) 减掉哪些方案:
任意一个不在 \(w\) 但在 \(r\) 里的方案,在 \(i\) 到 \(j\) 之间还经过至少一个点,设这些点中最小的是 \(k\)。
那么从 \(i\) 到 \(k\) 的方案就是 \(w_{i,k}\),从 \(k\) 到 \(j\) 的方案就是 \(r_{k,j}\)。
枚举 \(i\le k\le j\) ,
最后 dp 使用 \(w\) 转移即可。复杂度也是 \(O(k^3)\)。
类似上面的考虑,我们发现用 \(w\) 算出来的终点 dp 值,其实是相同的算法,不过是把 \(r\) 的乘积换成 \(w\) 的乘积。算出来的自然就是去了重的方案。
最后总结一下,用没去重的 \(r\) 计算两点间的路径,算出来的是“至少”的、重数为组合数的方案 \(F\) 或 \(f\);而用去了重的 \(w\) 计算两点间的路径,算出来的直接就是恰好的方案 \(G\) 或 \(g\) 。
\(f\) 和 \(g\),\(F\) 和 \(G\) 之间是某种偏序下带某种系数的前缀和关系,准确的说是 \(G\to F\) 是带组合系数的线性全序集上的后缀和关系,\(g\to f\) 是集合包含偏序集上的的后缀和关系。要想得到反转的关系 \(F\to G\) 和 \(f\to g\),必须经历反演的过程,前者是二项式反演,后者是子集反演。(注意如果我们并不想求单个的 G 而是全体 G,那么用反演关系反而效率更低,在这个要求下我们可以充分利用已算出的 G 来求未算出的 G)
而 \(f\to F\) 和 \(g\to G\) 可以看做一个状态压缩的关系。\(F\) 是将状态集合大小相同的所有 \(f\) 压在一起的产物,G 也类似。从这个角度我们可以看出这两种反演有着密不可分的联系。
浙公网安备 33010602011771号