题解:CF2187D Cool Problem

· · 题解

在 duel 中想到的神奇思路,但当时脑子一团乱麻写炸了调不过样例,队友帮我调出来了。

c 写作 ax+by 的形式。遇到一个 0 时将 a 增加 1;遇到一个 1 时将 a 取反,b 异或 1

再将 f 也写作 Ax+By 的形式。B 的贡献相对简单:可以发现 iB 有贡献当且仅当 1\sim i 中有奇数个 1。至于 A 的贡献,手玩发现遇到第一个 1 时取反后 -a 和末尾的那个 a 抵消了,所以无论何时没有被抵消的 a 形如 1\sim k 的一段等差数列。

问题是如何找到这个 k。我们以 i 为横坐标、a 为纵坐标画折线图。考虑所有 a=0 的点将折线图划分成若干段,其中最后一段是没满的。发现除了最后一段其他段都是被抵消的,所以 A=\frac{|a_n|(|a_n|+1)}2

对于最后一段,1\sim i 中有奇数个 1i|a|1,有偶数个 1i|a|1。且除了最后一段其他段不对 |a| 产生贡献。发现 2(i-|a|) 等于 1\sim i 中有奇数个 1i 的数量。直接用 bitset 优化 dp 维护它即可,f_{i,j,0/1} 表示 1\sim i 中有奇数个 1i 的数量为 j,当前 1\sim i1 的数量是偶数还是奇数,是否可行。

这是代码,很短。