BZOJ 4260 Codechef REBXOR(字典树)

题意

N<=4*105

题解

看起来一副不可做的样子是吧,,,
如果只看前半部分的式子呢?
再看看后半部分...
发现  前缀异或一下  trie树上查一查  后缀异或一下  trie树上查一查
F[i]表示r1<=i的最大值 G[i]为l2>=i的最大值    两部分相加    搞定~

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=401001;
 8 struct tree{
 9     int nxt[4];
10 }tr[N*35];
11 int n,c[N],f[N],g[N],ans,sum,tot;
12 inline void insert(int a){
13     int now=0,z;
14     for(int i=31;i>=1;i--){
15         if(a&(1<<(i-1)))z=1;
16         else z=0;
17         if(!tr[now].nxt[z]){
18             tr[now].nxt[z]=++tot;
19             memset(tr[tot].nxt,0,sizeof(tr[tot].nxt));
20         }
21         now=tr[now].nxt[z];
22     }
23 }
24 inline int check(int x){
25     int tmp=0;
26     int now=0,z;
27     for(int i=31;i>=1;i--){
28         if(x&(1<<(i-1)))z=1;
29         else z=0;
30         if(tr[now].nxt[!z]){
31             tmp=(tmp<<1)+1;
32             now=tr[now].nxt[!z];
33         }
34         else{
35             tmp=tmp<<1;
36             now=tr[now].nxt[z];
37         }
38     }
39     return tmp;
40 }
41 void init(){
42     memset(tr[0].nxt,0,sizeof(tr[0].nxt));
43     tot=0;
44 }
45 int main(){
46     scanf("%d",&n);
47     insert(0);
48     for(int i=1;i<=n;i++){
49         scanf("%d",&c[i]);
50         sum^=c[i];
51         f[i]=f[i-1];
52         f[i]=max(f[i],check(sum));
53         insert(sum);
54     }
55     init();
56     sum=0;
57     insert(0);
58     for(int i=n;i>=1;i--){
59         sum^=c[i];
60         g[i]=g[i+1];
61         g[i]=max(g[i],check(sum));
62         insert(sum);
63     }
64     for(int i=1;i<=n-1;i++){
65         ans=max(ans,f[i]+g[i+1]);
66     } 
67     printf("%d",ans);
68     return 0;
69 }

 

posted @ 2018-08-30 11:18  Xu-daxia  阅读(137)  评论(0编辑  收藏  举报