ORSum

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,虽然学习过,我还是不太了解,以后补。

code

posted @ 2023-08-03 21:21  wscqwq  阅读(21)  评论(0编辑  收藏  举报