BZOJ 4260 Codechef REBXOR (01Trie)
题目大意:给你一个序列,当$1<=l_{1}<=r_{i}<l_{2}<=r_{2}<=n$,求$a_{l1}^...a_{r1}+a_{l2}^...a_{r2}$的最大值
一直在想怎么用可持久化$Trie$搞这道题,卡了一个半小时,看完题解发现我是$sb$,根本不用可持久化
把 区间异或和 转化为 区间端点前缀和的异或值$pa_{i}$,每次先把$pa_{i}$在$Trie$里找到能和它异或得到的最大值$w$
则在$i$之前能取到的异或最大值$lx_{i}$就是,$lx_{i}=max(lx_{i-1},w)$
再把$pa_{i}$插入$Trie$里
后缀也这样做一次就行了
1 #include <cmath> 2 #include <queue> 3 #include <vector> 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #define N1 400100 8 #define N2 12000100 9 #define MM 100 10 #define ll long long 11 #define dd double 12 #define uint unsigned int 13 #define mod 1000000007 14 #define idx(X) (X-'a') 15 using namespace std; 16 17 int gint() 18 { 19 int ret=0,fh=1;char c=getchar(); 20 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 21 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 22 return ret*fh; 23 } 24 int n; 25 int a[N1],bin[31]; 26 struct Trie{ 27 int ch[N2][2],tot; 28 void init(){memset(ch,0,sizeof(ch));tot=1;} 29 void insert(int s) 30 { 31 int x=1,p; 32 for(int i=29;i>=0;i--){ 33 p=(s&bin[i])?1:0; 34 if(!ch[x][p]) 35 ch[x][p]=++tot; 36 x=ch[x][p]; 37 } 38 } 39 uint query_max(int s) 40 { 41 uint ans=0;int x=1,p; 42 for(int i=29;i>=0;i--){ 43 p=(s&bin[i])?1:0; 44 if(ch[x][p^1]){ 45 x=ch[x][p^1]; 46 ans+=bin[i]; 47 }else if(ch[x][p]){ 48 x=ch[x][p]; 49 }else break; 50 }return ans; 51 } 52 }T; 53 uint lx[N1],rx[N1]; 54 uint pa[N1],sa[N1]; 55 56 int main() 57 { 58 //freopen("t1.in","r",stdin); 59 scanf("%d",&n); 60 for(int i=0;i<=29;i++) 61 bin[i]=(1<<i); 62 for(int i=1;i<=n;i++) 63 a[i]=gint(); 64 T.init(),T.insert(0); 65 for(int i=1;i<=n;i++) 66 { 67 pa[i]=pa[i-1]^a[i]; 68 lx[i]=max(lx[i-1],T.query_max(pa[i])); 69 T.insert(pa[i]); 70 } 71 T.init(),T.insert(0); 72 for(int i=n;i>=1;i--) 73 { 74 sa[i]=sa[i+1]^a[i]; 75 rx[i]=max(rx[i+1],T.query_max(sa[i])); 76 T.insert(sa[i]); 77 } 78 uint ans=0; 79 for(int i=1;i<n;i++) 80 ans=max(ans,lx[i]+rx[i]); 81 printf("%u\n",ans); 82 return 0; 83 }