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 }

 

posted @ 2018-11-27 12:59  guapisolo  阅读(174)  评论(0编辑  收藏  举报