题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5536
题意:
给定n个个数s1, s2… sn,求最大的(si+sj)^sk且满足(i!=j!=k)。
题解:
很明显的一道字典树题目,把每个数都插入字典树,枚举两个数的和。考虑到可能会有重复的数,每次枚举到i,j时首先在字典树上删除 si 和 sj 然后再查询 si+sj 。
代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
int n,m,tot,T,cnt[70005];
int tr[70005][2],s[1005];
void init(int i)
{
tr[i][1]=tr[i][0]=0;
cnt[i]=0;
}
void add(int x,int id)
{
int now=0;
for (int i=31;i>=0;i--)
{
int p=0;
if (((1<<i)&x)!=0) p=1;
if (!tr[now][p])
{
tot++;
tr[now][p]=tot;
init(tot);
}
now=tr[now][p];
cnt[now]+=id;
}
}
int query(int x)
{
int now=0;
int tmp=0;
for (int i=31;i>=0;i--)
{
int p=1;
if (((1<<i)&x)!=0) p=0;
if (!tr[now][p] || cnt[tr[now][p]]<=0) now=tr[now][!p];
else tmp+=(1<<i),now=tr[now][p];
}
return tmp;
}
int main()
{
scanf("%d",&T);
while(T--)
{
tot=0;
init(tot);
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&s[i]);
add(s[i],1);
}
int ans=-1;
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
{
add(s[i],-1);
add(s[j],-1);
ans=max(ans,query(s[i]+s[j]));
add(s[i],1);
add(s[j],1);
}
memset(cnt,0,sizeof(cnt));
printf("%d\n",ans);
}
}
时间: 2024-10-29 19:07:57