Solution
要求选出一段子序列使得异或值最大。发现异或运算具有类似于前缀和的性质:由于 的性质,可以快速消除前缀影响。
设 为
到
的异或值,则
即为
到
的异或值。问题转化为对每个
查询使得异或值最大的
,字典树实现即可。
需要注意的是,异或运算的优先级低于 ,判断时需要加括号。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e5+10;
int n,m,tot=1,pre[N],trie[N<<5][2];
void Insert(int x){
int y,p=1;
for(int i=21;i>=0;i--){
y=(x>>i)&1;
if(!trie[p][y])
trie[p][y]=++tot;
p=trie[p][y];
}
}
int query(int x){
int y,p=1,res=0;
for(int i=21;i>=0;i--){
y=((x>>i)&1)^1;
if(trie[p][y])
p=trie[p][y],res|=(1<<i);
else if(trie[p][y^1])
p=trie[p][y^1];
else
break;
}
return res;
}
int main(){
cin>>n;
int x;
for(int i=1;i<=n;i++)
cin>>x,pre[i]=pre[i-1]^x;
int ans=-1,l,r;
Insert(0);
for(int i=1;i<=n;i++){
x=query(pre[i]);
if(x>ans)
ans=x,r=i;
Insert(pre[i]);
}
for(int i=r-1;i>=0;i--)
if((pre[i]^pre[r])==ans){
l=i+1;
break;
}
cout<<ans<<" "<<l<<" "<<r;
return 0;
} 
京公网安备 11010502036488号