hiho1860——最大異或和
阿新 • • 發佈:2018-11-02
給一個數組,求出區間最大異或和
01字典樹的典型應用,不過這個不是求和某個數x異或的最大值,而是要求出區間,區間的問題我們可以轉成字首和,比如查詢與pre[2]異或最大的值,然後用這個求出的異或pre[2]就是3-k這一段的異或和了,然後為了保持查詢的索引一定是再右邊,所以一邊掃查詢一邊插入新的(再後面的字首和)
有一個坑點,不能從32位開始,要從31開始,32就會wa…
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+50;
int tree[33*N][2];
int a[33*N];
int pre[N];
int cnt;
int x,n;
void init(){
memset(tree,0,sizeof(tree));
memset(a,0,sizeof(a));
cnt=0;
}
void insert(int x,int p){
int root=0;
for(int i=31;i>=0;i--){
int id=(x>>i)&1;
if(!tree[root][id]){
tree[root][id]=++cnt;
}
root= tree[root][id];
}
a[root]=p;
}
int query(int x){
int root=0;
for(int i=31;i>=0;i--){
int id=(x>>i)&1;
if(tree[root][id^1]){
root=tree[root][id^1];
}
else{
root=tree[root][id];
}
}
return a[root];
}
int main(void){
printf("%d %d\n",2147483647>>32,2147483647>>31);
scanf("%d",&n);
init();
for(int i=1;i<=n;i++){
scanf("%d",&x);
pre[i]=pre[i-1]^x;
}
insert(pre[0],0);
int Max=0;
for(int i=1;i<=n;i++){
int k=query(pre[i]);
//printf("%d %d\n",ans,pre[i]);
Max=max(Max,pre[i]^pre[k]);
insert(pre[i],i);
}
printf("%d\n",Max);
return 0;
}