[CF662C]Binary Table
壹、题目描述 ¶
贰、一些思考 ¶
这是二刷,知道这是一道 \(\tt FWT\) 的妙妙题 但是可能还是不会
关注点在 \(n\le 20\),那我们就来暴力枚举我们翻转了哪些行吧?
现在我们已知每一行的翻转状况,对于每一列,我们一定要取其最优值,有一种朴素的方案是再扫一遍每一列,判断最优情况即可。
但是这样真的可以接受吗?显然是不行的。考虑我们目前枚举的翻转行在二进制下的数为 \(s\),对于第 \(i\) 列,将其初始状态记为 \(\omega_i\),那么在 \(s\) 的变换下,实际第 \(i\) 列就是 \(\omega_i\oplus s\),换句话说,我们要求的是
然后我就不会了...... 二刷都不会,我真的是个废物
叁、题解 ¶
设 \(f(x)=\min\{\text{bitcnt}(x),n-\text{bitcnt}(x)\}\),对于一个 \(s\),我们考虑它的贡献,为
但是这个 \(s\) 放在参数里面,有没有什么办法能把他拿出来?我们考虑在外层加上一个循环枚举 \(\omega_i\oplus s\) 的结果,那么
可以将相同的 \(\omega_i\) 整合起来,设 \(t_x\) 为所有列中,二进制为 \(x\) 的列的个数,那么枚举 \(m\) 无用了,变成了一个 \(2^n-1\) 的枚举,即
嘿,发现了点什么没有?如果我们记 \(Ans=g(s)\),那么就有
然后,这就变成板子了......将两个长度为 \(2^n\) 的数组用异或卷积卷起来,得到 \(g\),再在 \(g\) 中取最大值即为答案。
叁、参考代码 ¶
\(\color{red}{\text{talk is FWT, but I have no code.}}\)
肆、用到 の \(\tt trick\)
柿子中的 \(\min,\max\) 有时候都很烦,考虑把这些东西去掉,这里直接将其记为一个函数,眼不见心不烦啊......
另外,当自变量在函数之内时,此处用到的处理方法是将参数的值整体拿出来枚举,并加上一个布尔表达式,这样不影响结果。