题目:
给定一数组, 求一对位置 i, j 且有arr[i] ^ arr[j]值最大, 输出最大值
解法:
暴力求肯定不妥,
所以需要一种快速的存储此前所有数字的数据结构
并通过异或贪心求出最大值
简单推导:
异或, 不进位加法, 同零异一
所以当前位置的最优解即为此前所有数字中, 与当前数二进制位相异的最多且最优即为解
最优很简单, 从高位到低位不同最优, 高位的权重大,这个很好理解
所以可以用trie储存此前数的二进制位并贪心求解
代码
/*
Zeolim - An AC a day keeps the bug away
*/
//pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <sstream>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
typedef long double ld;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const int MAXN = 2e7 + 10;
int trie[MAXN][2] = {0}, cnt = 1;
void insert(ll x)
{
int to = 1;
for(int i = 31; i >= 0; --i)
{
int val = (x >> i) & 1;
if(!trie[to][val])
trie[to][val] = ++cnt;
to = trie[to][val];
}
}
ll rfind(ll x)
{
ll ret = 0;
int to = 1;
for(int i = 31; i >= 0; --i)
{
int val = ((x >> i) & 1) ^ 1;
if(!trie[to][val])
to = trie[to][val ^ 1];
else
to = trie[to][val], ret = ret + (1 << i);
}
return ret;
}
int main()
{
//ios::sync_with_stdio(false);
//cin.tie(0); cout.tie(0);
//freopen("D://test.in", "r", stdin);
//freopen("D://test.out", "w", stdout);
ll n, x, ans = 0;
cin >> n;
for(int i = 0; i < n; ++i)
{
cin >> x;
if(i)
ans = max(ans, rfind(x));
insert(x);
}
cout << ans << '
';
return 0;
}