入门oj 6451: The XOR Largest Pair之二
Description
今天小W用了1s不到的时候完成了这样一个题:
在给定的N个整数 A_1,A_2,…,A_N中选出两个进行异或运算,得到的结果最大是多少?
正当他志得意满时,L老师亮出了另一个题:
给你1000个数字a1到a1000,从其中选出三个数字ai,aj,ak
(1<=i,j,k<=1000,且i,j,k互不相同)
满足(ai+aj)xor ak的值最大
小W顿时迷茫了.........
在给定的N个整数 A_1,A_2,…,A_N中选出两个进行异或运算,得到的结果最大是多少?
正当他志得意满时,L老师亮出了另一个题:
给你1000个数字a1到a1000,从其中选出三个数字ai,aj,ak
(1<=i,j,k<=1000,且i,j,k互不相同)
满足(ai+aj)xor ak的值最大
小W顿时迷茫了.........
Input
第一行给出数字N,接下来N行,每行一个数字
Output
如题
Sample Input
4
1
2
3
4
Sample Output
7
HINT
(1+2)xor4=7
sol
trie题
具体做法:
1把每一个数字转为二进制,放入一个trie
2枚举每两个数的和,枚举一遍,因为是做异或运算,所以可以从高位往地位取(越高越好)
你会发现选的数字是不能重复的,所以要先把选的数从trie里面删掉
代码如下:
#include<cstring> #include<iostream> using namespace std; const long long maxn=1e5+10; long long a[310001][11],tot,sum[1001],End[maxn],ans; char str[maxn]; void ins(long long str,long long vol)//如果vol==1 就是把一个数加进来,反之,就是删去那个数 { long long p=0; for(long long i=31;i>=0;i--) { long long l=(str>>i)&1; if(!a[p][l]) a[p][l]=++tot; p=a[p][l]; End[p]+=vol; }//trie模板,不会自学 } long long find(long long str) { long long p=0; long long ans=0; for(long long i=31;i>=0;i--) { long long l=(str>>i)&1;//算出第i位是几 if(a[p][l^1]) ans=ans<<1|1,p=a[p][l^1]; else ans=ans<<1,p=a[p][l];//ans=ans<<1|1相当于在ans=ans<<1的第i位加1 } return ans; } int main(){ long long n,m; cin>>n; tot=0; for(long long i=1;i<=n;i++) cin>>sum[i],ins(sum[i],1); for(long long i=1;i<=n;i++) for(long long j=i+1;j<=n;j++){ ins(sum[i],-1); ins(sum[j],-1);//删除 ans=max(ans,find(sum[i]+sum[j])); ins(sum[i],1); ins(sum[i],1);//再加回来 } cout<<ans; return 0; }
外送一个网址http://begin.lydsy.com/JudgeOnline/discuss3/thread.php?tid=735
you are both faker