比赛的时候这道题想了好久,最后还是没想到正解,一直提醒队友不要暴力,暴力一定不过,最后看那么多人都过了,我们还没想到正解,于是就暴力了,
分析:把所有数2进制分解,建一颗Trie树,然后暴力
因为要保证
trie树每一个节点维护一个
复杂度
下面是代码:
#include <bits/stdc++.h>
#define LL long long
#define FOR(i,x,y) for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)
using namespace std;
const int maxn = 1010;
int ch[maxn*35][2],cnt[maxn*35],sz;
void Init(){
memset(ch,0,sizeof(ch));
memset(cnt,0,sizeof(cnt));
sz = 0;
}
void Insert(int* str){
int u = 0;
FOR(i,0,35){
if(!ch[u][str[i]]){
ch[u][str[i]] = ++sz;
}
u = ch[u][str[i]];
cnt[u] ++;
}
}
void Delete(int* str){
int u = 0;
FOR(i,0,35){
u = ch[u][str[i]];
cnt[u] --;
}
}
LL calc(int* str){
LL res = 0;
int u = 0;
FOR(i,0,35){
if(ch[u][1^str[i]] && cnt[ch[u][1^str[i]]]){
res |= (1LL<<(34-i));
u = ch[u][1^str[i]];
}
else{
u = ch[u][str[i]];
}
}
return res;
}
int a[maxn],s[maxn][35],n;
void deal(){
Init();
int str[35];
FOR(i,0,n){
scanf("%d",&a[i]);
int num = a[i];
FOR(j,0,35){
str[j] = num%2;
num >>= 1;
}
FOR(j,0,35) s[i][j] = str[34-j];
Insert(s[i]);
}
}
void work(){
int str[35];
int strr[35];
LL ans = 0;
FOR(i,0,n-1){
Delete(s[i]);
FOR(j,i+1,n){
Delete(s[j]);
int num = a[i]+a[j];
FOR(k,0,35){
str[k] = num%2;
num >>= 1;
}
FOR(k,0,35) strr[k] = str[34-k];
LL res = calc(strr);
ans = max(ans,res);
Insert(s[j]);
}
Insert(s[i]);
}
printf("%I64d\n",ans);
}
int main()
{
//freopen("test.in","r",stdin);
int T; scanf("%d",&T);
while(T--){
scanf("%d",&n);
deal();
work();
}
return 0;
}