题意可转化为:把 分成
个连续子数组,第
个子数组的异或和为
,要求最大化
,其中
表示按位与。
设某种分割得到的答案为
记 表示非负整数
二进制表示中是 1 的位的集合。由按位与的性质有:
下面讨论 。
情况一:
为奇数
令整段异或为
由于分段只是把整段异或拆开再异或回去,
取任意一位 。由于
对所有
都成立,即第
位上每个
都是
,于是
在第
位上的值等于
个
的异或:
- 由
为奇数,
所以第 位在
中也为 1,即
。
因此对任意 ,都有
,即
奇数段方案的最优值为
,即不可能超过
的值。
情况二:
为偶数,且 
因为 ,所以我们可以取一个 奇数
满足
(例如
)。
定义
显然 ,并且这对应原数组在第
段结束处切一刀得到的 两段异或。
接下来证明:
从而说明任何偶数段方案的答案都不会超过某个两段切分的答案。
取任意 ,则
的第
位都是
。
- 因为
是奇数,
的第
位是奇数个
的异或,等于
,所以
;
- 因为
也是奇数,
的第
位同理也为
,所以
。
于是
这对所有 都成立,因此
偶数段(
)的最优值一定能由某个
的切分达到。
C++ Code
#include <bits/stdc++.h>
template<typename T>
void chmax(T &a, T b) {
if (a < b) {
a = b;
}
}
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (auto &x: a) {
std::cin >> x;
}
std::vector<int> s(n + 1);
for (int i = 0; i < n; i++) {
s[i + 1] = s[i] ^ a[i];
}
int ans = s[n];
for (int i = 1; i < n; i++) {
chmax(ans, s[i] & (s[n] ^ s[i]));
}
std::cout << ans << "\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int T = 1;
std::cin >> T;
while (T--) {
solve();
}
return 0;
}

京公网安备 11010502036488号