【Trie 字典树】Nikitosh and xor
时间限制: 1 Sec 内存限制: 128 MB
提交: 4 解决: 2
题目描述
Nikitosh the painter has a 1-indexed array A of N elements. He wants to find the maximum value of expression
(A[l1] ⊕ A[l1 + 1] ⊕ … ⊕ A[r1]) + (A[l2] ⊕ A[l2 + 1] ⊕ … ⊕ A[r2]) where 1 ≤ l1 ≤ r1 < l2 ≤ r2 ≤ N.
Here, x ⊕ y means the bitwise XOR of x and y.
Because Nikitosh is a painter and not a mathematician, you need to help him in this task.
输入
The first line contains one integer N, denoting the number of elements in the array.
The second line contains N space-separated integers, denoting A1, A2, … , AN.
输出
Output a single integer denoting the maximum possible value of the given expression.
样例输入
5
1 2 3 1 2
样例输出
6
提示
2 ≤ N ≤ 4*105
0 ≤ Ai ≤ 109
题目大意:给你n个数字,让你求两段互不交叉的序列分别的亦或和之和的最大值
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 4e5 + 5;
int trie[maxn * 30][2];
int tot = 1;
ll poww[40];
ll l[maxn],r[maxn];
ll zz[maxn];
void insert(ll p)
{
int tmp = 1;
for (int i = 30; i >= 0; --i)
{
int tmpp;
if (p & poww[i])
tmpp = 1;
else
tmpp = 0;
if (!trie[tmp][tmpp])
trie[tmp][tmpp] = ++tot;
tmp = trie[tmp][tmpp];
}
}
ll findd(ll p)
{
int tmp = 1;
ll ans = 0;
for (int i = 30; i >= 0; --i)
{
int tmpp;
if (p & poww[i])
tmpp = 1;
else
tmpp = 0;
if (trie[tmp][tmpp ^ 1])
{
ans += poww[i];
tmp = trie[tmp][tmpp ^ 1];
}
else
tmp = trie[tmp][tmpp];
}
return ans;
}
void init()
{
poww[0] = 1;
for (int i = 1; i <= 30; ++i)
poww[i] = poww[i - 1] << 1;
}
int main()
{
// freopen("in.txt", "r", stdin);
int n;
init();
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
{
ll tmp;
scanf("%lld", &tmp);
zz[i] = tmp ^ zz[i - 1];
}
insert(0);
for (int i = 1; i <= n; ++i)
{
l[i] = max(l[i - 1], findd(zz[i]));
insert(zz[i]);
} //从左往右插入字典树
memset(trie, 0, sizeof(trie));
tot = 1;
for (int i = n; i > 0; --i)
{
r[i] = max(r[i + 1], findd(zz[i]));
insert(zz[i]);
} ////从右往左插入字典树
ll ans = 0;
for (int i = 1; i <= n; ++i)
ans = max(ans, l[i] + r[i]);
printf("%lld\n", ans);
return 0;
}