HDU 5536 Chip Factory (枚举+01Trie)

来源:互联网 发布:淘宝卖家授权 编辑:程序博客网 时间:2024/06/08 10:47


Chip Factory

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


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.

1T1000
3n1000
0si109
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
231 2 33100 200 300
 

Sample Output
6400
 

Source
2015ACM/ICPC亚洲区长春站-重现赛(感谢东北师大)
 

Recommend
hujie
 

Statistic | Submit | Discuss | Note


题意:给你n个数(n<=1e3), 求max( (a[i] + a[j]) ^ a[k] ) (i, j, k都不相同)


思路:先将n个数建立01Trie,然后枚举i,j,从01Trie中删除a[i]和a[j],然后去查询与(a[i]+a[j])异或的最大值,查询完后再插回去。


另外,删除操作是这样实现的,我们每个节点记录一个cnt值





插入时对所有经过节点的val值加1,删除就将对应节点的cnt值减1

在树上贪心匹配的时候就只走那些cnt值为正的节点。

#include <iostream>#include <cstring>#include <cstdio>#include <vector>#include <algorithm>using namespace std;const int maxn = 1e5 + 5;int a[maxn], ch[maxn][2], cnt[maxn], id, n;char str[15];void Insert(int x){    int rt = 0;    for(int i = 31; i >= 0; i--)    {        int tmp = (x>>i)&1;        if(!ch[rt][tmp])        {            memset(ch[id], 0, sizeof(ch[id]));            cnt[id] = 0;            ch[rt][tmp] = id++;        }        rt = ch[rt][tmp];        cnt[rt]++;    }}void Delete(int x){    int rt = 0;    for(int i = 31; i >= 0; i--)    {        int tmp = (x>>i)&1;        rt = ch[rt][tmp];        cnt[rt]--;    }}int match(int x){    int rt = 0, ans = 0;    for(int i = 31; i >= 0; i--)    {        int tmp = (x>>i)&1;        if(ch[rt][tmp^1] && cnt[ch[rt][tmp^1]])        {            ans |= (1<<i);            rt = ch[rt][tmp^1];        }        else            rt = ch[rt][tmp];    }    return ans;}int main(){    int t;    cin >> t;    while(t--)    {        memset(ch[0], 0, sizeof(ch[0]));        id = 1;        scanf("%d", &n);        for(int i = 1; i <= n; i++)            scanf("%d", &a[i]), Insert(a[i]);        int ans = -2e9;        for(int i = 1; i <= n; i++)        {            Delete(a[i]);            for(int j = i+1; j <= n; j++)            {                Delete(a[j]);                ans = max(ans, match(a[i]+a[j]));                Insert(a[j]);            }            Insert(a[i]);        }        printf("%d\n", ans);    }    return 0;}