Chip Factory
Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2620 Accepted Submission(s): 1161
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亚洲区长春站-重现赛(感谢东北师大)
这题数据弱,可以 O(n3) 卡过去
正经解法:
将每个数转化为二进制值,插入到字典树中
枚举
val=~(a[i]+a[j])
,并在字典树中删除对应的
a[i],a[j]
val的第i位=x,如果字典树中存在第i位==x的
−−>ans+=(1<<i);
否则,查找字典树第i位==x^1
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<string>
#include<vector>
#include<deque>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<ctime>
#include<string.h>
#include<math.h>
#include<list>
using namespace std;
#define ll long long
#define pii pair<int,int>
const int inf = 1e9 + 7;
const int N = 1e3+5;
inline int read(){
int x;
char ch;
while(!isdigit(ch=getchar()));
x=ch-'0';
while(isdigit(ch=getchar())){
x=x*10+ch-'0';
}
return x;
}
int a[N];
const int CHARSET=2,BASE='0',MAX_NODE=32*1000;
struct Trie{
int tot,root,child[MAX_NODE][CHARSET];
int flag[MAX_NODE];//flag[i]>0 存在 flag[i]=0:被删了
Trie(){
memset(child[1],0,sizeof(child[1]));
flag[1]=0;
root=tot=1;
}
void insert(int val){
int*cur=&root;
for(int i=30;i>=0;--i){
int x=(val&(1<<i))>0;
cur=&child[*cur][x];
if(*cur==0){
*cur=++tot;
memset(child[tot],0,sizeof(child[tot]));
flag[tot]=0;
}
++flag[*cur];
}
}
void erase(int val){
int*cur=&root;
for(int i=30;i>=0;--i){
int x=(val&(1<<i))>0;
cur=&child[*cur][x];
--flag[*cur];
}
}
int query(int val){
int*cur=&root;
int ans=0;
for(int i=30;i>=0;--i){
int x=(val&(1<<i))>0;
int*tmp=&child[*cur][x];
if(*tmp!=0&&flag[*tmp]>0){
ans+=(1<<i);
cur=tmp;
}
else{
cur=&child[*cur][x^1];
}
}
return ans;
}
void clear(){
memset(child[1],0,sizeof(child[1]));
flag[1]=0;
root=tot=1;
}
}trie;
int slove(int n){
int ans=0;
for(int i=0;i<n;++i){
trie.erase(a[i]);
for(int j=i+1;j<n;++j){
trie.erase(a[j]);
ans=max(ans,trie.query(~(a[i]+a[j])));
trie.insert(a[j]);
}
trie.insert(a[i]);
}
return ans;
}
int main()
{
//freopen("/home/lu/Documents/r.txt","r",stdin);
//freopen("/home/lu/Documents/w.txt","w",stdout);
int T=read();
while(T--){
int n=read();
trie.clear();
for(int i=0;i<n;++i){
a[i]=read();
trie.insert(a[i]);
}
printf("%d\n",slove(n));
}
return 0;
}