[ARC120F] Wine Thief
好题,难度并不算很高,但是支持多种思考方式,做法又极其优雅。
贡献是线性的加减法,对于每个位置的贡献只与选了它的方案数有关,考虑拆贡献。拆贡献后自然想到先计算方案数,而遗憾的是对于每个位置的方案数几乎是本质不同的,两边限制独立但要求选的总和为 \(k\),是个棘手的问题。
现在有两种选择,一种是先思考更简单的情况的方案数,一种是直接思考如何处理问题。
我认为选择前者更为稳妥,如果计数能力稍微差了点,并不知道一个长度为 \(n\) 的序列选 \(k\) 个且满足要求的方案数怎么算,能做到多少复杂度,有什么性质,很有可能就算想到了解法,也以为不可做。就比如说我的第一反应就是变成环然后处理 \(1,n\) 都选了的方案数,发现问题还是很棘手,因为我根本没用弄清楚最简单的问题的精确做法。
而对于拆贡献绝大多数题显然都需要我们搞清楚全局的方案数怎么计算。相当于 \(n\) 个球排成一排,我们考虑刻画不能相邻的限制,我们钦定选择的每个球前面必须也带着一个球,至于说第一个球的问题,我们在最前面多加一个球就是了,容易发现这么做的方案与原问题构成双射,那么方案数即为 \(\binom{n+1-k}{k}\),设其为 \(f(n,k)\)。
这个时候我们再去考虑如何处理每个位置的方案数,现在我们希望把两边结合在一起,因为我们不可能去对两边枚举选了多少个,这至少是 \(\mathcal{O}(nk)\) 的。此时我们自然想到把原问题的链改成环的处理方式,此时方案数为 \(f(n-3,k-1)\),当然如果该位置在 \(1,n\) 就是 \(f(n-2,k-1)\)。但是此时 \(1,n\) 都选的方案是没有算上的。不过我们发现当钦定 \(1,n\) 都选时我们进入了一个子问题,子问题仍然可以放在一起处理,也就是说方案数是以一种 \(\sum_{i=0} f(n-3-4i,k-2i-1)\) 的形式出现,我们前缀和维护之,再处理一些 corner case 即可。复杂度可以做到线性。代码。

浙公网安备 33010602011771号