题目描述
John is a manager of a CPU chip factory, the factory produces lots of chips everyday. To manage large amounts of products, every processor has a serial number. More specifically, the factory produces n chips today, the i-th chip
produced this day has a serial number si.
At the end of the day, he packages all the chips produced this day, and send it to wholesalers. More specially, he writes a checksum number on the package, this checksum is defined as below:
which i, j, k are three different integers between 1 and n. And is symbol of bitwise XOR.
Can you help John calculate the checksum number of today?
输入
The first line of input contains an integer T indicating the total number of test cases.
The first line of each test case is an integer n, indicating the number of chips produced today. The next line has n integers s1 , s2 ,…, sn , separated with single space, indicating serial number of each chip.
1≤T≤1000
3≤n≤1000
0≤s i≤109
There are at most 10 testcases with n > 100
输出
For each test case, please output an integer indicating the checksum number in a line.
样例输入
2
3
1 2 3
3
100 200 300
样例输出
6
400
题意: 给序列A,找到i,j,k使得序列中(Ai+Aj)^Ak最大。i≠j≠k
题解: 关于异或值最大的问题容易想到01字典树,问题在于三种数不能重复用,那么两层for暴力枚举Ai+Aj,使其异或01字典树上的Ak,记录一个最大值即可,不能重复用的情况,每次枚举到第i个和第j个值时,在字典树上删除这两个值,那么k就不会查询到和两者相同的位置了。删除后注意要加回字典树上
#include<bits/stdc++.h> #define LL long long #define M(a,b) memset(a,b,sizeof a) #define pb(x) push_back(x) using namespace std; const int maxn=1e3+7; int tre[maxn<<5][2]; int cnt[maxn<<5]; int tot; void insert(LL a,int rt,int add) { for(int i=31; i>=0; i--) { int x=(a>>i)&1; if(!tre[rt][x]) { tre[rt][x]=++tot; M(tre[tre[rt][x]],0); } rt=tre[rt][x]; cnt[rt]+=add; } } LL finds(LL a,int rt) { LL ans=0; for(int i=31;i>=0;i--) { ans<<=1; int x=(a>>i)&1; if(tre[rt][!x]&&cnt[tre[rt][!x]])rt=tre[rt][!x],ans|=1; else rt=tre[rt][x]; } return ans; } int t,n; LL a[1080]; int main() { scanf("%d",&t); while(t--) { LL ans=0; tot=0; int rt=++tot; M(tre[rt],0); M(cnt,0); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); insert(a[i],rt,1); } for(int i=1;i<n;i++) { insert(a[i],rt,-1); for(int j=i+1;j<=n;j++) { insert(a[j],rt,-1); ans=max(ans,finds(a[i]+a[j],rt)); insert(a[j],rt,1); } insert(a[i],rt,1); } printf("%lld\n",ans); } }
来源:https://www.cnblogs.com/kuronekonano/p/11135694.html