タイトル説明:
農家のジョンは、牛に餌をやるときに問題に遭遇しました。
彼は合計N頭の牛を飼っています。
各給餌の前に、N頭の牛が1〜Nの順に並んでいます。
さらに、各牛には一意ではない可能性のある整数が割り当てられます。
次に、割り当てられたすべての整数が長さNの整数シーケンスを形成します。
サブシーケンス内の要素のXOR合計を最大化できるように、整数シーケンス内の連続する空でないサブシーケンスを見つけてください。
そのようなシーケンスが複数ある場合は、シーケンスの最後にある整数に対応する牛の番号が小さいシーケンスを選択します。
それでも複数の代替シーケンスがある場合は、長さが最も短いものを選択してください。
入力フォーマット
最初の行には整数Nが含まれています。
行2〜N + 1では、各行に整数が含まれ、行iiの整数は、i-1の番号が付けられた牛に割り当てられた整数値を表します。
出力フォーマット
最大のXOR合計を表す3つの整数、選択したシーケンスの最初の整数に対応する牛の番号、および選択したシーケンスの最後の整数に対応する牛の番号をそれぞれ出力します。
データ範囲
1≤N≤10^ 5の場合
、牛に割り当てられる整数の範囲は[0,2 ^ 21-1]です。
入力サンプル:
5
1
0
5
4
2
サンプル出力:
6 4 5
#include <iostream>
#include <cstdio>
using namespace std;
const int MAX = 100009;
int son[MAX * 21][2]; // son[p][u] 表示结点编号为p的u儿子(这个题只有0 1两个儿子)的编号
int n, idx;
int s[MAX], id[MAX * 21];
void insert_trie(int num, int k)
{
int p = 0;
for(int i = 20; i >= 0; i--)
{
int u = num >> i & 1;
if(!son[p][u])
son[p][u] = idx++;
p = son[p][u];
}
id[p] = k;
}
int query(int x)
{
int p = 0;
for(int i = 20; i>= 0; i--)
{
int u = x >> i & 1;
if(son[p][!u])
p = son[p][!u];
else
p = son[p][u];
}
return id[p];
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d", &s[i]);
s[i] = s[i] ^ s[i - 1];
}
insert_trie(s[0], 0);
int maxx = -1, l, r;
for(int i = 1; i <= n; i++)
{
int k = query(s[i]);
int t = s[i] ^ s[k];
if(t > maxx)
{
maxx = t;
l = k + 1;
r = i;
}
insert_trie(s[i], i);
}
printf("%d %d %d\n", maxx, l, r);
return 0;
}