1. 程式人生 > >hiho1860——最大異或和

hiho1860——最大異或和

給一個數組,求出區間最大異或和
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; }