版权声明:本文为博主原创作品, 转载请注明出处! https://blog.csdn.net/solider98/article/details/83864338
思路分析:
易知, 题目等价于计算i, j, 其中i, j满足1 =< i < j <= N且异或最大, 对于任意的2 <= x <= N, 考虑计算使得1 <= y < x且异或最大的异或的值, 可将插入一个只含有字符'0'和'1'的Tire树T中, 其中每个对应一个31位的二进串, 最高位对应字符串起始字符. 接下来以对应的二进制串为依据, 从T的根, 尽量选择与当前对应字符('0'或'1'相异的分支), 直至到达叶结点, 此叶结点对应的二进制串即为. 下面给出AC代码, 易知, 下述程序的时间复杂度为O(31N).
//CH1602_The XOR Largest Pair
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAX = 31e5 + 5, NIL = (1ll << 31) - 1;
int trie[MAX][2], tot;
int main(){
int ans = -NIL, N; scanf("%d", &N);
for(int i = 1; i <= N; ++i){
int tans = 0, k = 0, t; scanf("%d", &t);
for(int j = 30; j >= 0; --j){
int b = t >> j & 1;
if(trie[k][!b]) k = trie[k][!b], tans |= 1 << j;
else k = trie[k][b];
}
ans = max(ans, tans);
//将t插入trie中
k = 0;
for(int j = 30; j >= 0; --j){
int b = t >> j & 1;
if(!trie[k][b]) trie[k][b] = ++tot;
k = trie[k][b];
}
}
printf("%d\n", ans);
}