BZOJ 4260: Codechef REBXOR(01trie+思维)

求两个不相交区间异或和的和最大.

设l[i]是1~i一段区间的最大异或和,r[i]是i~n一段区间的最大异或和,题意就是求max(l[i]+r[i+1]);

那么只要求l,r数组。

设num数组是个前缀异或和,根据异或的性质,我们要求i~j的异或和就是num[i]^num[j],所以对于l数组,我们要求出max(num[i]^num[j]),r数组用后缀异或和同理.

l[i]=max(l[i-1],find(num[i-1]^a[i])) l[i-1]表示区间不包括i,否则就是用find函数找区间包括i的值.find函数就是再trie树上尽量往相反的方向爬。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <queue>
 7 #include <map>
 8 #define ll long long
 9 #define out(a) printf("%d",a)
10 #define writeln printf("\n")
11 const int N=4e5+50;
12 const int MOD=1e9+7;
13 using namespace std;
14 int n;
15 int tot=1;
16 int a[N];
17 int num[N],l[N],r[N];
18 int trie[N*31][2];
19 int ans;
20 int read()
21 {
22     int s=0,t=1; char c;
23     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
24     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
25     return s*t;
26 }
27 ll readl()
28 {
29     ll s=0,t=1; char c;
30     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
31     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
32     return s*t;
33 }
34 void insert(int x)
35 {
36     int u=1;
37     for (int i=31;i>=0;i--){
38       int c=((1<<i)&x)>0;
39       if (!trie[u][c]) trie[u][c]=++tot;
40       u=trie[u][c];
41     }
42 }
43 int find(int x)
44 {
45     int u=1,res=0;
46     for (int i=31;i>=0;i--){
47       int c=((1<<i)&x)>0;
48       if (trie[u][1-c]) u=trie[u][1-c],res+=(1<<i);
49       else u=trie[u][c];
50     }
51     return res;
52 }
53 int main()
54 {
55     n=read();
56     for (int i=1;i<=n;i++){
57       a[i]=read();
58       insert(num[i-1]);
59       num[i]=num[i-1]^a[i];
60       l[i]=max(l[i-1],find(num[i]));
61     }
62     memset(trie,0,sizeof(trie));
63     for (int i=n;i;i--){
64       insert(num[i+1]);
65       num[i]=num[i+1]^a[i];
66       r[i]=max(r[i+1],find(num[i]));
67       ans=max(ans,l[i]+r[i+1]);
68     }
69     out(ans);
70     return 0;
71 }
72     
73     
View Code

 

posted @ 2018-08-30 22:51  Kaleidoscope233  阅读(127)  评论(0编辑  收藏  举报