题意:求下面这个公式的最大值:
maxi,j,k(si+sj)⊕sk
思路:如果用普通方法你要分别枚举3个数,n^3感觉会超时的。
然而完全莫有想到能用字典树,你先把所有的数保存下来,然后删去要用的i和j,再在里面找出能和a[i]+a[j]异或出的最大值。相当于值需要枚举i和j即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 1e3+9;
int vec[MAX_N];
int res[35];
struct node
{
long long int val,num;
node *next[2];
node()
{
val = num = 0;
next[0] = next[1] = NULL;
}
};
node *root = new node;
void insertnode(int x)
{
node *p = root , *q;
for(int i=31;i>=0;i--)
{
int t = (x>>i)&1;
if(!p->next[t])
{
q = new node;
q->num = 1;
p->next[t] = q;
p = p->next[t];
}
else
{
p = p->next[t];
p->num ++;
}
}
p->val = x;
}
long long int query(int x)
{
node *p = root , *q;
for(int i=31;i>=0;i--)
{
int t = (x>>i)&1;
if(p->next[t^1] && ((p->next[t^1])->num))
{
p = p->next[t^1];
}
else
{
p = p->next[t];
}
}
return p->val;
}
void deletenode(int x)
{
node *p = root , *q;
for(int i=31;i>=0;i--)
{
int t = (x>>i)&1;
p->next[t]->num -- ;
p = p->next[t];
}
}
void dealnode(node *x)
{
if(!x) return ;
if(x->next[0]) dealnode(x->next[0]);
if(x->next[1]) dealnode(x->next[1]);
delete(x);
}
int main()
{
int N,M,T;
cin>>T;
while(T--)
{
root = new node;
scanf("%d",&N);
for(int i=0;i<N;i++)
{
scanf("%d",&vec[i]);
insertnode(vec[i]);
}
long long int ans = -1;
for(int i=0;i<N-1;i++)
{
for(int j=i+1;j<N;j++)
{
deletenode(vec[i]);
deletenode(vec[j]);
long long int temp = query(vec[i]+vec[j]);
ans = max(ans,(vec[i]+vec[j])^temp);
insertnode(vec[i]);
insertnode(vec[j]);
}
}
cout<<ans<<endl;
dealnode(root);
}
}