John is a manager of a CPU chip factory, the factory produces lots of chips everyday. To manage large amounts of products, every processor has a serial number. More specifically, the factory produces n chips today, the i-th chip produced this day has a serial number si.
At the end of the day, he packages all the chips produced this day, and send it to wholesalers. More specially, he writes a checksum number on the package, this checksum is defined as below:
maxi,j,k(si+sj)⊕sk
which i,j,k are three different integers between 1 and n. And ⊕ is symbol of bitwise XOR.
Can you help John calculate the checksum number of today?
Input
The first line of input contains an integer T indicating the total number of test cases.
The first line of each test case is an integer n, indicating the number of chips produced today. The next line has n integers s1,s2,..,sn, separated with single space, indicating serial number of each chip.
1≤T≤1000
3≤n≤1000
0≤si≤109
There are at most 10 testcases with n>100
Output
For each test case, please output an integer indicating the checksum number in a line.
Sample Input
2
3
1 2 3
3
100 200 300
Sample Output
6
400
第一次把二进制与字典树结合在一起,感觉十分奇妙。
这道题目就是把所有数字化成二进制然后建立一颗字典树,
由于si范围是10^9,二进制长度最多为31,我们把每个数字都化成长度为31的二进制,
方便处理。
然后我们统计每个节点的数量。
每次就是删掉trie树中的si,sj,然后把si+sj与trie树中的节点比较。
例如如果该(si+sj)某位是1,我们就在trie树沿着root往下找0,如果有0,继续找,如果没有0,那么该位置取反,
一直找到底即可。
比较完我们要把si,sj重新插入trie树中。
位运算: 1&(x>>i) 判断x某位是0还是1
x^(1<<i) 将x第i位取反
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<ctime>
#include<string>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#include<set>
#include<map>
#include<cstdio>
#include<limits.h>
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define mes(x, m) memset(x, m, sizeof(x))
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define INF 1e9+7
#define inf 0x3f3f3f3f
#define Pi 4.0*atan(1.0)
#define lowbit(x) (x&(-x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-9;
const int maxn = 1000*30+10;
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
struct trie{
int next[maxn][2],cot[maxn],tot,rt;
int creatNode(){
for(int i=0;i<2;++i){
next[tot][i]=-1;
cot[next[tot][i]]=0;
}
++tot;
return tot-1;
}
void init(){
tot=0;
rt=creatNode();
}
void insert(int x){
int cur=rt;
for(int i=30;i>=0;--i){
int c=1&(x>>i);
if(next[cur][c]==-1){
next[cur][c]=creatNode();
}
cur=next[cur][c];
++cot[cur];
}
}
void del(int x){
int cur=rt;
for(int i=30;i>=0;--i){
int c=1&(x>>i);
cur=next[cur][c];
--cot[cur];
}
}
int query(int x){
int cur=rt;
for(int i=30;i>=0;--i){
int c=1&(x>>i);
if(1==c){
if(next[cur][0]!=-1&&cot[next[cur][0]]){
cur=next[cur][0];
}else{
cur=next[cur][1];
x^=(1<<i);
}
}else{
if(next[cur][1]!=-1&&cot[next[cur][1]]){
cur=next[cur][1];
x^=(1<<i);
}else{
cur=next[cur][0];
}
}
}
return x;
}
};
int num[1001];
trie tre;
int main(){
int t=read();
while(t--){
mes(tre.next,-1);
mes(tre.cot,0);
tre.init();
int n=read();
int ans=0;
for(int i=0;i<n;++i){
num[i]=read();
tre.insert(num[i]);
}
for(int i=0;i<n;++i){
tre.del(num[i]);
for(int j=i+1;j<n;++j){
tre.del(num[j]);
ans=max(ans,tre.query(num[i]+num[j]));
tre.insert(num[j]);
}
tre.insert(num[i]);
}
printf("%d\n",ans);
}
return 0;
}