CF1977D XORificator
题意
给你一个二进制(仅由 \(0\) 和 \(1\) 组成)\(n \times m\) 矩阵。你可以进行以下操作任意次:反转某一行中的所有值(即用 \(1\) 替换 \(0\),用 \(0\) 替换 \(1\))。
矩阵中的某一列如果只包含一个 \(1\),则被视为特殊列。你的任务是找出最多有多少列可以同时被特殊化,以及为达到这一目的应在哪几行反转。
\(1\le nm\le 3\times 10^5\)
题解
我们发现,如果我们钦定第 \(j\) 列的第 \(i\) 行位置为 \(1\),其他行位置为 \(0\)。会发现其实我们确定了整个矩阵。它的反转方式也是唯一确定的。
于是可以考虑枚举每一列,得到钦定某一个位置为 \(1\) 时哪些行需要反转。
在最多列出现的反转方案就是答案。于是我们可以将一种反转方案哈希起来,放入 map
进行统计,这里我用的随机权值异或的哈希方法。
接着考虑如何 \(\mathcal O(1)\) 求出反转方案的哈希值。
可以统计前后缀的哈希值,为 \(1\) 视作反转,为 \(0\) 视作不反转,一个位置为 \(1\) 的反转方案应该为前后缀的反转方案加上这一位的相反状态。
于是我们就可以 \(\mathcal O(nm)\) 的解决掉这道题。
总结
-
找供需关系
看答案的贡献并找到使得这个贡献进入答案的要求