题目大意:给一个有n个数的数列, 从这个数列中取三个数(不能是同一个数), 使两个数和与另一个数异或。 求所有组合中的最大值。即 max( (s[i] + s[j]) ^ s[k]) i, j, k ∈(1~n);
解题思路:听说漂亮的暴力可以过·······
我还是用字典树吧···, 首先呢, 我们枚举i, j; 然后在字典树上搜索有没有一个数可以使他俩的和异或之后最大。
代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1000050;
int tot = 1, root = 1;
int A[10000];
struct Tree
{
int ch[2], size;
}T[maxn];
void init()
{
for(int i=0; i<maxn; i++)
T[i].size = T[i].ch[0] = T[i].ch[1] = 0;
}
void Insert(int x)
{
int p = root;
int t;
T[p].size++;
for(int i=30; i >= 0; --i)
{
if(x & (1 << i)) t = 1;
else t = 0;
if(T[p].ch[t] == 0) T[p].ch[t] = ++tot;
p = T[p].ch[t];
T[p].size++;
}
}
void Delete(int x)
{
int p = root;
T[p].size--;
int t;
for(int i=30; i>=0; --i)
{
if(x & (1 << i)) t = 1;
else t = 0;
p = T[p].ch[t];
T[p].size--;
}
}
int Query(int x)
{
int p = root;
int t;
for(int i=30; i >= 0; --i)
{
if(x & (1 << i)) t = 1;
else t = 0;
if(t)
{
if(T[p].ch[0] && T[T[p].ch[0]].size > 0) p = T[p].ch[0];
else
{
x ^= (1 << i);
p = T[p].ch[1];
}
}
else
{
if(T[p].ch[1] && T[T[p].ch[1]].size > 0) {p = T[p].ch[1]; x ^= (1 << i);}
else
{
p = T[p].ch[0];
}
}
}
return x;
}
int main()
{
int Case;
scanf("%d", &Case);
while(Case--)
{
init();
int n, ans = 0;
scanf("%d", &n);
for(int i=0; i<n; i++)
{
scanf("%d", &A[i]);
Insert(A[i]);
}
for(int i=0; i<n; i++)
{
Delete(A[i]);
for(int j=i+1; j<n; j++)
{
Delete(A[j]);
ans = max(ans, Query(A[i] + A[j]));
Insert(A[j]);
}
Insert(A[i]);
}
printf("%d\n", ans);
}
return 0;
}