HDU 5536 Chip Factory
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5536
题意:从n个数中找一个i,j,k,使得(a[i]+a[j])^a[k]的值最大,输出最大值
求异或最大可以使用字典树
那么我们只要枚举 i 和 j 就可以了
但是在找k之前必须先从字典树中删去 i 和 j ,找完之后再插入回去
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> using namespace std; const int N=1005; int a[N],ch[31*N][2],val[31*N]; int tot; void init() { tot=0; memset(ch[tot],0,sizeof(ch[tot])); memset(val,0,sizeof(val)); } void add(int x,int y) { int now=0; for(int i=30;i>=0;i--) { int t=x>>i&1; if (!ch[now][t]) { ch[now][t]=++tot; memset(ch[tot],0,sizeof(ch[tot])); } now=ch[now][t]; val[now]+=y; } } int Find(int x) { int now=0,ans=0; for(int i=30;i>=0;i--) { int t=x>>i&1; if (ch[now][t^1]&&val[ch[now][t^1]]) { ans|=1<<i; now=ch[now][t^1]; } else now=ch[now][t]; } return ans; } int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); init(); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); add(a[i],1); } int ans=0; for(int i=1;i<n;i++) { add(a[i],-1); for(int j=i+1;j<=n;j++) { add(a[j],-1); int t=Find(a[i]+a[j]); ans=max(ans,t); add(a[j],1); } add(a[i],1); } printf("%d\n",ans); } return 0; }