农夫约翰在给他的奶牛们喂食时遇到了一个问题。
他共有 N N N 头奶牛,编号 1 1 1∼ N N N。
每次喂食前,这 N N N 头奶牛会按照 1 1 1∼ N N N 的顺序站成一排。
此外,每头奶牛都被分配了一个可能不唯一的整数。
那么所有被分配的整数就形成了一个长度为 N N N 的整数序列。
请你在该整数序列中找出一个连续的非空子序列,使得子序列中元素的异或和能够最大。
如果存在多个这样的序列,那么选择序列末端整数对应的奶牛编号更小的那个序列。
如果仍然存在多个可选的序列,那么选择长度最短的那个序列。
输入格式
第一行包含整数
N
N
N。
第 2 2 2∼ N + 1 N+1 N+1 行,每行包含一个整数,其中第 i i i 行的整数表示编号为 i − 1 i−1 i−1 的牛被分配的整数值。
输出格式
输出三个整数,分别表示最大的异或和,所选序列首端整数对应的奶牛编号,所选序列末端整数对应的奶牛编号。
数据范围
1
≤
N
≤
1
0
5
1≤N≤10^5
1≤N≤105,
分配给奶牛的整数的范围是
[
0
,
2
21
−
1
]
[0,2^{21}−1]
[0,221−1]。
输入样例:
5
1
0
5
4
2
输出样例:
6 4 5
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int maxn=1e5+10;
int n;
int a[maxn];
int trie[maxn*21][2];
int pos[maxn*21];
int tot;
void insert(int i) {
int p = 0, x = a[i];
for (int i = 20; i >= 0; i--) {
int cur = x >> i & 1;
if (!trie[p][cur]) trie[p][cur] = ++tot;
p = trie[p][cur];
}
pos[p] = i;
}
pii Search(int x) {
int p = 0, res=0;
for (int i = 20; i >= 0; i--) {
int cur = x >> i & 1;
if (trie[p][!cur]) {
p = trie[p][!cur];
res = res * 2 + !cur;
} else {
p = trie[p][cur];
res = res * 2 + cur;
}
}
return {res, pos[p]};
}
int mx,l,r;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
a[i] ^= a[i - 1];
insert(i);
pii p = Search(a[i]);
if ((p.first ^ a[i]) > mx) {
mx = (p.first ^ a[i]);
l = p.second + 1;
r = i;
}
}
if (n == 1) {
printf("%d 1 1\n", a[1]);
return 0;
}
if (l == r && r == 2) l = r = 1;
printf("%d %d %d\n", mx, l, r);
return 0;
}