Chip Factory
Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 427 Accepted Submission(s): 230
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:
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?
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
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
Recommend
解题报告:
1≤T≤1000
3≤n≤1000
0≤si≤109
3≤n≤1000
0≤si≤109
There are at most
10
testcases with
n>100
题意:输入n个数,求最大的(a+b)^c。(a、b、c要互不相同。)
建立字典树,把一个int型的数存放到字典树,里面每个结点有两条路径,nex[0]和nex[1],代表这个结点的下一个节点是0还是1,并且有一个cnt表示有多少个数 在该位置(位运算,该结点表示的位置)是0或1(和该结点表示的数字 相同)。
字典树深度较小的点,表示的位数越高。
由于n最多有1000个,字典树的深度是32,那么数组大小超过1000*32即可。
for两重循环,表示a和b,如果a和b序号相同,则跳过。
然后在字典树里面,把a和b经过的每个结点的cnt--。(就是在字典树里拆掉a和b。)
然后遍历字典树,找到最优解:如果在树的某一层上,(a+b)在该位是1,那么找这一层有没有0的,若是0,则找1(贪心)。
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson num<<1,le,mid
#define rson num<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn=1010 ;
//const int maxm= ;
int n,root,cnt,a[maxn];
struct Node
{
int num;
int nex[2];
Node()
{
num=nex[1]=nex[0]=0;//严重错误:num=nex[1]=nex[2]=0;
};
} node[maxn*33];
int newNode()
{
node[++cnt]= Node();
return cnt;
}
void build(int x)
{
int s=root, y;
for(int i=30;i>=0;i--)
{
if(x&(1<<i)) y=1;
else y=0;
/*这个是极端错误的写法!!!: int y= (x&(1<<i) );*/
Node & now=node[s];
if(now.nex[y]==0) now.nex[y]=newNode();
s=now.nex[y];
node[s].num++;
}
}
void delet(int x)
{
int s=root,y;
for(int i=30;i>=0;i--)
{
if(x&(1<<i)) y=1;
else y=0;
Node & now=node[s];
s=now.nex[y];
node[s].num--;
}
}
int query(int x)
{
int s=root,y;
for(int i=30;i>=0;i--)
{
if(x&(1<<i)) y=1;
else y=0;
Node &now=node[s];
int ne=y;
//下面的if else 原来出错严重,在于ne的取值
if(y)
{
if(now.nex[0]&& node[now.nex[0]].num) ne=0 ;
else x^= ( 1<<i) ;
}
else
{
if(now.nex[1]&& node[now.nex[1]].num) x^= (1<<i) ,ne=1 ;
else ;
}
s=now.nex[ne];
}
return x;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
cnt=0;
root=newNode();
for(int i=1;i<=n;i++) scanf("%d",&a[i]),build(a[i]);
int maxi=0;
for(int i=1;i<=n;i++)
{
delet(a[i]);
for(int j=1;j<=n;j++)
{
if(j==i) continue;
delet(a[j]);
maxi=max(maxi,query(a[i]+a[j]) );
build(a[j]);
}
build(a[i]);
}
printf("%d\n",maxi);
for(int i=1;i<=cnt;i++)
{
node[i].num=node[i].nex[0]=node[i].nex[1]=0;
}
}
return 0;
}