题意:从 n n n个数 s 1 , s 2 . . . s n s_1,s_2...s_n s1,s2...sn中选出 3 3 3个下标不同的数,求: m a x ( i , j , k ) ( ( s i + s j ) ⨁ s k ) max_{(i,j,k)}((s_i+s_j)\bigoplus s_k) max(i,j,k)((si+sj)⨁sk)
思路:
考虑将所有数插入字典树,然后枚举
i
,
j
i,j
i,j,从字典树中删去
s
i
,
s
j
s_i,s_j
si,sj后拿
(
s
i
+
s
j
)
(s_i+s_j)
(si+sj)去匹配最大值即可。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int A = 1e3 + 10;
int Trie[A<<5][2],val[A<<5],cnt[A<<5],a[A],tot,n;
void insert(ll v,int add){
int u = 0;
for(int i=32 ;i>=0 ;i--){
int c = (v>>i)&1;
if(!Trie[u][c]){
Trie[u][c] = ++tot;
cnt[tot] = 0;val[tot] = 0;
memset(Trie[tot],0,sizeof(Trie[tot]));
}
u = Trie[u][c];
cnt[u]+=add;
}
val[u] = v;
}
ll query(ll v){
int u = 0;
for(int i=32 ;i>=0 ;i--){
int c = (v>>i)&1;
if(cnt[Trie[u][c^1]]>0) u = Trie[u][c^1];
else u = Trie[u][c];
}
return val[u];
}
int main(){
int T;scanf("%d",&T);
while(T--){
tot = 0;memset(Trie[0],0,sizeof(Trie[0]));
scanf("%d",&n);
for(int i=1 ;i<=n ;i++) {scanf("%d",&a[i]);insert(a[i],1);}
ll ans = 0;
for(int i=1 ;i<=n ;i++){
insert(a[i],-1);
for(int j=i+1 ;j<=n ;j++){
insert(a[j],-1);
ll now = a[i]+a[j];
ans = max(ans,1LL*now^query(now));
insert(a[j],1);
}
insert(a[i],1);
}
printf("%I64d\n",ans);
}
return 0;
}