为啥写这篇文章
请移步这篇文章
boshi: 我有一个绝妙的思路和解释,不过尔等凡人听不懂
所以就有了这篇文章
然后这篇文章堪了一些 boshi 懒得改的已经更正的误
Problem
Solution
一道毒枭题,不同的状态可以得到不同复杂度的算法= =
为了防止歧义,我们约定一些变量的含义:m 为球的不同颜色数,第 i 种球有 ci 个,记 n=∑mi=1ci
记录非法的边数
让两个相邻且颜色相同的球连一条非法边。f[i][j] 表示前 i 种有 j 条非法边的方案数,枚举拆开的非法边有 l 个,第 i 个元素被分成了 t 段,那么有
f[i][k−l+ci−t]=∑k,l,tf[i−1][k](kl)(ci−1t−1)(n−k+1t−l)
复杂度的上界为 O(n3)
记录各颜色球的个数,容斥计数
g[n1,n2,⋯,nm] 表示第 i 种球有 ni 个时,没有相邻元素的方案数
f[n1,n2,⋯,nm] 表示第 i 种球有 ni 个时,随意排的方案数,显然等于 (∑mi=1ni)!∏mi=1ni!
用高维容斥即可得到
g[n1,n2,⋯,nm]=∑ai≤ni(−1)∑ni−∑ai∏(niai)(∑ai)!∏ai!
=(−1)∑ni∑ni∑N=0(−1)NN!∏∑ai=N(niai)ai!
∑ai=N 其实就是卷积,用分治 FFT 可以把时间复杂度优化至 O(nlog2n)
枚举颜色的段数,第 i 种颜色的生成函数为:
Fi(x)=ci∑j=1(ci−1j−1)(−1)ci−jxjj!
要解释这个式子,需要反过来思考,从最终局面出发,枚举最终局面下的一种颜色被分成了多少段,然后把这个颜色全部删去,再考虑下一种颜色。其中 (−1)ci−j 来源于这种颜色贡献的非法边。[xi] 项的系数表达的是分成 i 段的方案数。
有另外一种解释的方法。每一项代表有多少段,只需要考虑各段之间的拼接即可,这个是 EGF。不难发现这个拼接过程并不能保证最终局面下的相邻颜色段是不同颜色。而所求的其实就是最后有 n 段的方案数,因此我们仍然需要容斥,容斥系数即为 (−1)n−i 。这个本质就是 DP,卷积就描述了 DP 的过程。
用分治 FFT 同样可以做到 O(nlog2n)
不难发现第二种和第一种的生成函数卷积出来的第 i 项的容斥系数是一致的,这两种容斥是殊途同归的。
于是乎这个生成函数就可以把容斥系数给去掉了,虽然叫 “带容斥系数的生成函数” 似乎有点名不副其实。
队长:这为啥不能叫 “带容斥系数的生成函数”,不然分治 FFT 的名字是怎么来的……
1 条评论
Qiuly · 2020年1月3日 3:13 下午
orz