1.题目链接。给定一个数组,找出来不相同的三个数使得(s[i]+s[j])^s[k]最大,并且输出这个最大值。
2.N^2枚举两个数,然后对这两个数先把他从字典树上删除,删完之后再查询和的最值,复杂度O(32*N^2).
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 1010;
int n, m;
LL a[maxn * 32];
LL ans;
struct Trie
{
LL x;
int ch[maxn * 32][2];
int val[maxn * 32];
int sz;
void init()
{
sz = 1;
memset(ch, 0, sizeof(ch));
memset(val, 0, sizeof(val));
}
void Insert(LL x)
{
int u = 0;
for (int i = 32; i >= 0; i--)
{
int c = (x >> i) & 1;
if (!ch[u][c])
{
ch[u][c] = sz++;
}
u = ch[u][c];
val[u]++;
}
}
void Del(LL x)
{
int u = 0;
for (int i = 32; i >= 0; i--)
{
int c = (x >> i) & 1;
u = ch[u][c];
--val[u];
}
}
LL query(LL x)
{
LL res = 0;
LL maxx = 0;
int u = 0;
for (int i = 32; i >= 0; i--)
{
int c = (x >> i) & 1;
if (ch[u][c ^ 1] && val[ch[u][c ^ 1]])
{
res += (1<< i);
maxx += ((c ^ 1)<< i);
u = ch[u][c ^ 1];
}
else
{
u = ch[u][c];
maxx += ((c)<<i);
}
}
return res;
}
}tr;
int main()
{
int T;
scanf("%d", &T);
LL x = 0;
while (T--)
{
tr.init();
scanf("%d\n", &n);
for (int i = 1; i <= n; i++)
{
scanf("%lld", &a[i]);
tr.Insert(a[i]);
}
LL ans = 0;
for (int i = 1; i <= n; i++)
{
tr.Del(a[i]);
for (int j = i + 1; j <= n; j++)
{
tr.Del(a[j]);
x = a[i] + a[j];
ans = max(ans, tr.query(x));
tr.Insert(a[j]);
}
tr.Insert(a[i]);
}
printf("%lld\n", ans);
}
return 0;
}