大致题意:给一个数组,找出这个数组的两个不相交区间的值 的最大和,区间的值是区间中的值的异或和。说得很奇怪,实在不清楚就耐心看题目中的公式。
大致思路:想办法得到每个位置 前面的 最大 连续区间异或值,和 后面的 最大 连续区间异或值。怎么得到?字典树就起了很大的作用,在遍历数组的时候,每次往01字典树中添加从前缀异或和(计算后面 的最大连续区间异或值的时候是用后缀异或和)。所以字典树中存的就是每一个位置的前缀异或和,每次把新的前缀异或和放入字典树中,同时再去查询能得到的前面 的最大连续区间异或值,同样,计算后面的最大区间异或值也是同样的方法。
最后,代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5+100;
int arr[maxn];
int premax[maxn];
int sufmax[maxn];
struct trie_tree
{
int trie[maxn*30][2];
int cur;
void Insert(int a)
{
int p=0;
for(int i=30;i>=0;--i)
{
int x=(a>>i&1)?1:0;
if(!trie[p][x])
trie[p][x]=++cur;
p=trie[p][x];
}
}
int query(int a)
{
int ans=0;
int p=0;
for(int i=30;i>=0;--i)
{
int x=(a>>i&1)?1:0;
if(trie[p][x^1])
ans+=(1<<i),p=trie[p][x^1];
else
p=trie[p][x];
}
return ans;
}
}A,B;
int main()
{
int n;
cin>>n;
for(int i=0;i<n;++i)
{
cin>>arr[i];
}
A.Insert(0);
B.Insert(0);
int temp=0;
for(int i=0;i<n;++i)
{
temp^=arr[i];
A.Insert(temp);
premax[i]=max(premax[i-1],A.query(temp));
}
temp=0;
for(int i=n-1;i>=0;--i)
{
temp^=arr[i];
B.Insert(temp);
sufmax[i]=max(sufmax[i+1],B.query(temp));
}
int ans=0;
for(int i=1;i<n;++i)
{
if(premax[i-1]+sufmax[i]>ans)
{
ans=premax[i-1]+sufmax[i];
}
}
cout<<ans<<endl;
return 0;
}