【题意】给出序列s[], 求max{(s[i]+s[j])^s[k]},其中i!=j!=k。
【分析】首先看下数据感觉N^3会爆炸,所以想到用字典序优化,枚举s[i]和s[j],那么从高位往低位查找和s[i]+s[j]尽量每位取反即可,对于三个位置不同,可以先插入所有序列,用到两个删除,用完恢复即可。这样复杂度是O(log2(s[i])*N^2)
【AC CODE】3120ms
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i,a,n) for(int i = a; i < n; i++)
#define repe(i,a,n) for(int i = a; i <= n; i++)
#define per(i,n,a) for(int i = n; i >= a; i--)
#define clc(a,b) memset(a,b,sizeof(a))
const int INF = 0x3f3f3f3f, MAXN = 1000+10,MAXM = 30;
int a[MAXN],node[MAXN*MAXM][2],vis[MAXN*MAXM],cnt;
void insert(int v, int add)
{
int u = 0;
per(i,MAXM-1,0)
{
int p = (bool)(v&(1<<i));
if(-1 == node[u][p])
node[u][p] = ++cnt;
u = node[u][p];
vis[u] += add;
}
}
int query(int v)
{
int ans = 0,u = 0;
per(i,MAXM-1,0)
{
int p = (bool)(v&(1<<i));
if(~node[u][p^1] && vis[node[u][p^1]])
u = node[u][p^1], ans = (ans<<1)+(p^1);
else if(~node[u][p] && vis[node[u][p]])
u = node[u][p], ans = (ans<<1)+p;
else
ans = ans<<1;
}
return ans;
}
int main()
{
#ifdef SHY
freopen("d:\\1.txt", "r", stdin);
#endif
int t;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
cnt = 0;
clc(node,-1);
clc(vis,0);
rep(i,0,n) scanf("%d", &a[i]),insert(a[i],1);
int ans = 0;
rep(i,0,n)
{
rep(j,i+1,n)
{
insert(a[i],-1);
insert(a[j],-1);
ans = max(ans,(a[i]+a[j])^query(a[i]+a[j]));
insert(a[i],1);
insert(a[j],1);
}
}
printf("%d\n", ans);
}
return 0;
}