4260: Codechef REBXOR
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2218 Solved: 962
[Submit][Status][Discuss]
Description
Input
输入数据的第一行包含一个整数N,表示数组中的元素个数。
第二行包含N个整数A1,A2,…,AN。
Output
输出一行包含给定表达式可能的最大值。
Sample Input
5
1 2 3 1 2
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。
Solution
用trie树处理出以$i$结尾的最大区间异或,前后分别扫一遍处理前缀和后缀。具体做法是将前缀或后缀插入trie树中,每次用前缀或后缀在trie树中查询异或最大,就是查询以$i$结尾的区间异或最大。
然后每个位置与前面取max,最后合并统计答案即可。
Code
#include<bits/stdc++.h> using namespace std; int n, a[400005], l[400005], r[400005]; int son[31*400005][2], tail; void read(int &x) { x = 0; char ch = getchar(); while(ch > '9' || ch < '0') ch = getchar(); while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } } void insert(int x) { int nd = 0; for(int i = 30; ~i; i --) { int t = 1 & (x >> i); if(!son[nd][t]) son[nd][t] = ++ tail; nd = son[nd][t]; } } int query(int x) { int nd = 0, ans = 0; for(int i = 30; ~i; i --) { int t = 1 & (x >> i); if(son[nd][!t]) { ans += (1 << i); nd = son[nd][!t]; } else if(son[nd][t]) nd = son[nd][t]; else break; } return ans; } int main() { read(n); int now = 0; insert(0); for(int i = 1; i <= n; i ++) { read(a[i]); now ^= a[i]; insert(now); l[i] = query(now); } for(int i = 1; i <= n; i ++) l[i] = max(l[i], l[i - 1]); now = 0; memset(son, 0, sizeof(son)); tail = 0; insert(0); for(int i = n; i >= 1; i --) { now ^= a[i]; insert(now); r[i] = query(now); } for(int i = n; i >= 1; i --) r[i] = max(r[i], r[i + 1]); long long ans = 0; for(int i = 1; i <= n; i ++) ans = max(ans, 1ll * (l[i] + r[i + 1])); printf("%lld", ans); return 0; }