【bzoj4260】 Codechef REBXOR trie树

 

Input

输入数据的第一行包含一个整数N,表示数组中的元素个数。
第二行包含N个整数A1,A2,…,AN。
 
 

 

Output

输出一行包含给定表达式可能的最大值。
 

 

Sample Input

5
1 2 3 1 2

Sample Output

6

Hint

 

满足条件的(l1,r1,l2,r2)有:(1,2,3,3),(1,2,4,5),(3,3,4,5)。

 

对于100%的数据,2 ≤ N ≤ 4*105,0 ≤ Ai ≤ 109。
 
题解:
其实很好想的,维护一个lmx[i]表示到1-i中最大的连续的xor和。
rmx[i]表示i-n重最大的连续的xor和,然后就是前缀和的形式
插入字典树,然后在字典树中找两个值的xor最大值。
就是找1的时候向0的方向找,0的时候向1的方向找。

很好理解吧。

 1 #include<cstring>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cstdio>
 6 #define N 400007
 7 using namespace std;
 8 
 9 int n,cnt=1;
10 int a[N],lmx[N],rmx[N];
11 struct Node
12 {
13     int point[2];
14     void init()
15     {
16         point[1]=point[0]=0;
17     }
18 }trie[400007*30];
19 
20 void insert(int x)
21 {
22     int now=1;
23     for (int i=31,t;i>=0;i--)
24     {
25         if (x&(1<<i)) t=1;
26         else t=0;
27         if (!trie[now].point[t]) trie[now].point[t]=++cnt;
28         now=trie[now].point[t];
29     }
30 }
31 int calc(int x)
32 {
33     int now=1,ans=0;
34     for (int i=31,t;i>=0;i--)
35     {
36         if (x&(1<<i)) t=1;
37         else t=0;
38         if (trie[now].point[t^1])
39         {
40             ans=ans+(1<<i);
41             now=trie[now].point[t^1];
42         }
43         else now=trie[now].point[t];
44     }
45     return ans;
46 }
47 int main()
48 {
49     scanf("%d",&n);
50     for (int i=1;i<=n;i++)
51         scanf("%d",&a[i]);
52     int x=0;insert(x);
53     for (int i=1;i<=n;i++)
54     {
55         x=x^a[i];
56         insert(x);
57         lmx[i]=max(lmx[i-1],calc(x));
58     }
59     
60     cnt=1;
61     for (int i=0;i<400007*30;i++) trie[i].init();
62     
63     x=0;insert(x);
64     for (int i=n;i>=1;i--)
65     {
66         x=x^a[i];
67         insert(x);
68         rmx[i]=max(rmx[i+1],calc(x));
69     }
70     int ans=-1;
71     for (int i=2;i<=n;i++)
72         ans=max(ans,lmx[i-1]+rmx[i]);
73     printf("%d\n",ans);    
74 }

 

posted @ 2017-10-25 21:02  Kaiser-  阅读(163)  评论(0编辑  收藏  举报