Chip Factory
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
题目要求在一个数组里找出下标不同的i,j,k,求a[i]+a[j]异或a[k]的最大值;
第一种解法,显然O(n^3)暴力;
但是这个暴力也有讲究,不能随便乱暴;
第二种解法,01字典树;
跟模板题最大的区别就是,我要从中拿两个下标不同的数来相加,和数组里另外一个数求异或值,显然拿出来的两个数就必须从树中消失,怎么消失呢?我们可以记录每个结点的经过值,消失就减一,添加就加一;
对于字典树来说,memset清0最好不要用,尤其是有多种测试数据时,非常耗时间;
代码:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
//ios::sync_with_stdio(false);
using namespace std;
const int N=50010;
const int M=200100;
const LL mod=1e9+7;
int tr[N][32],val[N],s[N],a[N];
int rt;
void init(){
rt=0;
tr[0][1]=0;
tr[0][0]=0;
// memset(tr,0,sizeof(tr));//尽量不要用
// memset(val,0,sizeof(val));
// memset(s,0,sizeof(s));
}
void add(int p){
int k=0;
for(int i=31;i>=0;i--){
int d=(p>>i)&1;
if(!tr[k][d]){
tr[k][d]=++rt;
tr[rt][0]=tr[rt][1]=0;
val[rt]=0;
s[rt]=0;
}
k=tr[k][d];
s[k]++;
}
val[k]=p;
}
void update(int p,int q){//从树中删除或者添加某个数
int k=0;
for(int i=31;i>=0;i--){
int d=(p>>i)&1;
if(!tr[k][d]) break;
k=tr[k][d];
s[k]+=q;
}
}
int search(int p){
int k=0;
for(int i=31;i>=0;i--){
int d=(p>>i)&1;
if(tr[k][d^1]&&s[tr[k][d^1]]) k=tr[k][d^1];
else k=tr[k][d];
}
return val[k]^p;
}
int main(){
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--){
init();
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
add(a[i]);
}
int mmax=0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
update(a[i],-1);
update(a[j],-1);//删除
mmax=max(mmax,search(a[i]+a[j]));
update(a[i],1);
update(a[j],1);//添加
}
}
cout<<mmax<<endl;
}
return 0;
}