ABC291G OR Sum
题意:有两个长度为 \(N\) 的序列 \(A,B\),可以给 \(A\) 序列向左循环移动若干位,求 \(\sum (A_i|B_i)\) 的最大值。\(N\le 5\times 10^5\) 而 \(0\le A_i,B_i\le 31\)。
题解:发现 or
操作有点点困难,那么我们就把两个序列取反,然后求 and
的最小值。
尝试形式化枚举每个移动数量的过程,比如枚举一个移位 \(j\),再枚举一个 \(i\) 计算答案。
这种位数特别少的题,就先枚举二进制位 \(k\),对于每一位分别处理。设 \(a,b\) 分别为序列 \(A,B\) 的第 \(k\) 位取反。
然后就是两个 0/1
序列合并操作,我们需要求出一个答案数组 \(c\),\(c_j=\sum a_i\times b_{(i+j)\% n}\)。
我们可以把 \(b\) 复制一遍,去掉取模 \(n\),问题就变成了求 \(c_j=\sum a_i\times b_{i+j}\)。
这个形式还不是我们熟悉的形式,我们应该熟悉的形式是 \(c_{i+j}=\sum a_i\times b_j\)。
怎么办呢?拿 \(k\) 替换 \((i+j)\),问题就变成了 \(c_{k-i}=\sum a_i\times b_k\)。
左边式子 \(i\) 符号负的不好看,问题就变成了 \(c_{k+i}=\sum a_{-i}\times b_k\)。
右边下标为负数的很不好看,因为我们需要存储 \(a\) 数组,所以把 \(a\) 数组反转(?)得到 \(a'\) 了,就是原来的存储 \(a_{-i}\) 的数组右移 \(n-1\) 位。
令 \(p=n-1-i\),原式= \(c_{k+p}=\sum a'_{p}\times b_k\)。由上可知,多项式实际的值只有 \([n-1,2n-2]\) 的这 \(n\) 位才有效。
发现就是多项式的形式,直接卷积即可。
时间复杂度 \(O(n\log n)\)。
至于FFT,虽然学习过,我还是不太了解,以后补。