HDU 5536 Chip Factory 【01字典树】

来源:互联网 发布:c语言对数ln 编辑:程序博客网 时间:2024/05/22 13:28


Chip Factory

Time Limit: 18000/9000 MS (Java/Others)    Memory Limit:262144/262144 K (Java/Others)
Total Submission(s): 3420    Accepted Submission(s): 1500

Problem Description

John is a manager of a CPU chip factory, the factory produces lots of chipseveryday. To manage large amounts of products, every processor has a serialnumber. More specifically, the factory producesn chips today,thei -thchip produced this day has a serial numbersi.

At the end of the day, he packages all the chips produced this day, and send itto 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 andn. 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 thetotal number of test cases.

The first line of each test case is an integer
n, indicating thenumber of chips produced today. The next line hasn integerss1,s2,..,sn, separated withsingle 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 aline.

 

 

Sample Input

2

3

1 2 3

3

100 200 300

 

 

Sample Output

6

400

 


【题意】


现在给出n个数,现在需要你你从中选出三个不同的数i , j , k 使得(ai+aj)^ak最大,求这个最大值。


【思路】


很明显的一个01字典树模板题,先把所有数都插入到字典树中,然后我们只要去枚举前面两个数求和再从字典树中查询与它异或能得到的最大值。


唯一有点需要考虑的是,一个数选了后就不能再选,于是我们需要每次选了后把它从字典树中删除,查询完后再重新插入即可。


时间复杂度O(n * n * 32)。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a))#define rush() int T;scanf("%d",&T);while(T--)typedef long long ll;const int maxn = 1005;const ll mod = 1e9+7;const int INF = 0x3f3f3f3f;const double eps = 1e-9;int n;int cnt;int a[maxn];int tree[maxn*35][2];int mark[maxn*35];int num[maxn*35];void init(){    cnt=0;    mst(tree,0);    mst(mark,0);    mst(num,0);}void insert(int x){    int now=0;    for(int i=32;i>=0;i--)    {        int w=(x&((ll)1<<i))>0;        if(tree[now][w]==0)        {            tree[now][w]=++cnt;        }        now=tree[now][w];        num[now]++;    }    mark[now]=x;}int query(int x){    int now=0;    for(int i=32;i>=0;i--)    {        int w=(x&((ll)1<<i))>0;        if(tree[now][!w]&&num[tree[now][!w]])            now=tree[now][!w];        else now=tree[now][w];    }    return x^mark[now];}void Delete(int x){    int now=0;    for(int i=32;i>=0;i--)    {        int w=(x&((ll)1<<i))>0;        now=tree[now][w];        num[now]--;    }}int main(){    rush()    {        init();        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);            insert(a[i]);        }        int Max=0;        for(int i=1;i<=n;i++)        {            Delete(a[i]);            for(int j=i+1;j<=n;j++)            {                Delete(a[j]);                Max=max(Max,query(a[i]+a[j]));                insert(a[j]);            }            insert(a[i]);        }        printf("%d\n",Max);    }    return 0;}