HDU5536 Chip Factory(Trie树,二进制)

来源:互联网 发布:windows 10 一周年 编辑:程序博客网 时间:2024/06/02 07:18

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 nn chips
today, the ii-th chip produced this day has a serial number sisi.

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 maxi,j,k(si+sj)⊕sk

which i,j,ki,j,k are three different integers between 11 and nn. 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 TT indicating the total
number of test cases.

The first line of each test case is an integer nn, indicating the
number of chips produced today. The next line has nn integers
s1,s2,..,sns1,s2,..,sn, separated with single space, indicating serial
number of each chip.

1≤T≤10001≤T≤1000 3≤n≤10003≤n≤1000 0≤si≤1090≤si≤109 There are at
most 1010 testcases with n>100n>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

思路

先说题意,给出一堆数,然后从这些数中找出两个数,求和,然后求出这个和异或另一个数的最大值,假设把这些数存在了数组a中,那么需要求出:

max{(a[i]+a[j])a[k]}(ijk)

首先,用O(n3)暴力肯定超时,我们需要用字典树来优化一下,首先,枚举一下两个数的所有组合,然后在字典树中删除这个数,然后查询与他异或值最大的。思路和HDU4825 Xor Sum(Trie树,二进制)一样,注意一下删除后还要插入就行了

代码

#include <cstdio>#include <cstring>#include <string>#include <set>#include <sstream>#include <cmath>#include <iostream>#include <stack>#include <queue>#include <vector>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define debug() puts("what the fuck!!!")#define ll long longusing namespace std;const int N=1010*32;int a[1010];struct dicTree{    struct node    {        int op;        int next[2];    } Tree[N];    int root,sz;    int newnode()    {        Tree[sz].next[0]=Tree[sz].next[1]=-1;        Tree[sz++].op=0;        return sz-1;    }    void init()    {        sz=0;        root=newnode();    }    void insert(int x)    {        int now=root;        for(int i=31; i>=0; i--)        {            int to=(x>>i)&1;            if(Tree[now].next[to]==-1)                Tree[now].next[to]=newnode();            now=Tree[now].next[to];            Tree[now].op++;        }    }    int del(int x)    {        int now=root;        for(int i=31; i>=0; i--)        {            int to=(x>>i)&1;            now=Tree[now].next[to];            Tree[now].op--;        }    }    int find(int a,int b)    {        del(a);        del(b);        int x=a+b;        int now=root,res=0;        for(int i=31; i>=0; i--)        {            int to=(x>>i)&1;            if(Tree[now].next[to^1]!=-1&&Tree[Tree[now].next[to^1]].op)//如果存在相反的                to^=1;            if(to)                res=res|(1<<i);            now=Tree[now].next[to];        }        insert(a);        insert(b);        return res^x;    }};dicTree T;int main(){    int t,n;    scanf("%d",&t);    while(t--)    {        T.init();        scanf("%d",&n);        for(int i=0; i<n; i++)        {            scanf("%d",&a[i]);            T.insert(a[i]);        }        int maxx=-inf;        for(int i=0; i<n; i++)            for(int j=i+1; j<n; j++)                maxx=max(maxx,T.find(a[i],a[j]));        printf("%d\n",maxx);    }    return 0;}
原创粉丝点击