#Description
n个数
找出最大的
(ai+aj)xor(ak)
#Algorithm
将所有数的二进制构造出Trie
从高往低构建
比如
11100
00111
10110
就构建成
然后每次把枚举ai, aj
把ai,aj从trie中删除 然后再trie中找~(ai+aj)
找的越深 值就越大
#Code
#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
const int maxn = 1000 + 10; //n节点个数
const int maxnode = 100000 + 10;
const int sigma_size = 2; //分支个数
int a[maxn];
struct Trie {
int ch[maxnode][sigma_size]; //节点为i的编号为j节点
int val[maxnode]; //附加信息
int sz; //节点总数
Trie() {
sz = 1; //构造函数是节点总数是1
memset(ch[0], 0, sizeof(ch[0]));
memset(val, 0, sizeof(val));
}
void put(int x, int v) {
int p = 0;
for(int i = 31; i >= 0; i--) { //为何是31
int id = (x>>i)&1;
if(!ch[p][id]) { //节点不存在
memset(ch[sz], 0, sizeof(ch[sz])); //清空新的节点
val[sz] = 0; //附加信息
ch[p][id] = sz++; //孩子数组指向新的节点
}
p = ch[p][id]; //往下邹
val[p] += v; //附加信息为v
}
}
int get(int x) {
int ans = 0, u = 0;
for(int i = 31; i >= 0; i--) {
ans *= 2;
int id = (x>>i)&1;
if(ch[u][id] && //有孩子
val[ch[u][id]]) { //孩子有附加信息
ans++;
u = ch[u][id]; //往下走
}
else
u = ch[u][1-id]; //走另外一边
}
return ans;
}
};
void solve() {
Trie trie;
memset(a, 0, sizeof(a));
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
trie.put(a[i], 1);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
trie.put(a[i], -1);
for (int j = i + 1; j < n; ++j) {
trie.put(a[j], -1);
ans = max(trie.get(~(a[i] + a[j])), ans);
trie.put(a[j], 1);
}
trie.put(a[i], 1);
}
printf("%d\n", ans);
}
int main() {
//freopen("in.txt", "r", stdin);
int t;
scanf("%d", &t);
for (int i = 0; i < t; i++) {
solve();
}
}