Chip Factory
Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 5258 Accepted Submission(s): 2358
Problem Description
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:
maxi,j,k(si+sj)⊕sk
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?
Input
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≤si≤109
There are at most 10 testcases with n>100
Output
For each test case, please output an integer indicating the checksum number in a line.
Sample Input
2 3 1 2 3 3 100 200 300
Sample Output
6 400
Source
2015ACM/ICPC亚洲区长春站-重现赛(感谢东北师大)
与HDU4825类似
https://blog.csdn.net/GYH0730/article/details/79821507
有关异或的题一定要先往2进制上想,这道题不同的地方是要先在字典树上删除a[i]与a[j],在查询与(a[i]+a[j])的和异或的最大值
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 400005;
struct Trie_node
{
int next[2];
int flag;
void init()
{
next[0] = next[1] = 0;
flag = 0;
}
}trie[MAXN];
int trie_n;
void Insert(int num)
{
int root = 0,t,next;
for(int i = 30; i >= 0; i--) {
if(num & (1 << i)) t = 1;
else t = 0;
next = trie[root].next[t];
if(next == 0) {
next = trie[root].next[t] = ++trie_n;
}
root = next;
trie[root].flag++;
}
}
void Delete(int num)
{
int root = 0,t;
for(int i = 30; i >= 0; i--) {
if(num & (1 << i)) t = 1;
else t = 0;
root = trie[root].next[t];
trie[root].flag--;
}
}
int Query(int num)
{
int root = 0,t,next;
for(int i = 30; i >=0; i--) {
if(num & (1 << i)) t = 1;
else t = 0;
if(t == 1) {
next = trie[root].next[0];
if(trie[next].flag > 0 && next) {
root = trie[root].next[0];
}
else {
root = trie[root].next[1];
num ^= (1 << i);
}
}
else {
next = trie[root].next[1];
if(trie[next].flag > 0 && next) {
root = trie[root].next[1];
num ^= (1 << i);
}
else {
root = trie[root].next[0];
}
}
}
return num;
}
int a[MAXN];
int main(void)
{
int T,n,ans;
scanf("%d",&T);
while(T--) {
for(int i = 0; i <= trie_n; i++) {
trie[i].init();
}
trie_n = 0;
scanf("%d",&n);
for(int i = 0; i < n; i++) {
scanf("%d",&a[i]);
Insert(a[i]);
}
ans = 0;
for(int i = 0; i < n; i++) {
Delete(a[i]);
for(int j = i + 1; j < n; j++) {
Delete(a[j]);
ans = max(ans,Query(a[i] + a[j]));
Insert(a[j]);
}
Insert(a[i]);
}
printf("%d\n",ans);
}
return 0;
}