hdu5536
题目
给你一个数组,求三个元素,使得两个的和异或第三个的值最大,三个数没有先后规定但序号要不同。
思路
首先构建一棵2进制的Tire树,枚举i,j把他们从Tire中删去,在Tire树中从高位到低位贪心结果,最后再把i,j插回去。
代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct node
{
int next[2];
int cnt;
void init()
{
cnt=0;
memset(next,-1,sizeof(next));
}
};
node T[100000];
int le;
void Insert(int a)
{
int p=0;
for(int i=30; i>=0; i--)
{
int x=(a>>i)&1;
if(T[p].next[x]==-1)
{
T[le].init();
T[p].next[x]=le++;
}
p=T[p].next[x];
T[p].cnt++;
}
}
void Delete(int a)
{
int p=0;
for(int i=30; i>=0; i--)
{
int x=(a>>i)&1;
if(T[p].next[x]==-1)
{
T[le].init();
T[p].next[x]=le++;
}
p=T[p].next[x];
T[p].cnt--;
}
}
int query(int a)
{
int ans=0;
int p=0;
for(int i=30; i>=0; i--)
{
int x=(a>>i)&1;
if(x==1)
{
if(T[T[p].next[0]].cnt!=0)
{
ans|=(1<<i);
p=T[p].next[0];
}
else
p=T[p].next[1];
}
else
{
if(T[T[p].next[1]].cnt!=0)
{
ans|=(1<<i);
p=T[p].next[1];
}
else
p=T[p].next[0];
}
}
return ans;
}
int a[1010];
int main()
{
int k;
scanf("%d\n",&k);
while(k--)
{
int maxx=0;
le=1;
T[0].init();
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
Insert(a[i]);
}
for(int i=0; i<n-1; i++)
{
Delete(a[i]);
for(int j=i+1; j<n; j++)
{
Delete(a[j]);
maxx=max(maxx,query(a[i]+a[j]));
Insert(a[j]);
}
Insert(a[i]);
}
printf("%d\n",maxx);
}
return 0;
}