看到这么多位运算,拆位考虑。
对于\(f(a,b)\)的一位,要么是0,要么是1。
该位是1,说明有某种\(b\)的排列,使得该位上\(a_i \oplus b_i\)均为1。(因为\(\&\)的结果是1,说明全都是1)。
那么我们要优先满足哪一位为1呢?
一个直接的想法是优先满足高位为1,因为\(2^k > 2^{k-1}+2^{k-1}+...+2^1+2^0\),当前位如果可以为1,那么令它为1肯定严格优于让低位为1的任何方案(让低位为1的任何方案最大就是全都都是1,但是这也更小)。
然后发现有的位是无法为1的,只有a中0和1的个数刚好等于b中1和0的个数时,这一位才可能为1。
首先找到最高的可以为1的位\(k\),上面证明了,这样子的方案一定是最优解。
然后考虑后面的位,类似的,我们也尽量让每一位都为1。但是这样有一个问题:\(k\)位为1的约束,限制了\(a\)和\(b\)之间的匹配。
一开始(求\(k\)的时候),\(a\)和\(b\)可以任意匹配。
然后,\(a\)中所有第\(k\)位是0的可以和\(b\)中所有第\(k\)位是1的排列,\(a\)中所有第\(k\)位是1的可以和\(b\)中所有第\(k\)位是0的排列。也就是说,原集合分裂成了两个子集。直接对这两个子集操作,也是\(O(n)\)的。
类似的,每次对于一个可以排列的\(a,b\)的集合计算贡献之后,都会让它分成两个子集,为了保证复杂度严格\(O(n)\),要把空集特判掉。
具体实现可以记录下标。
标签:该位,排列,可以,Maximum,子集,位是 From: https://www.cnblogs.com/zhangchenxin/p/17802380.html