HDU5536 Chip Factory(trie树)

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


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
第一次把二进制与字典树结合在一起,感觉十分奇妙。
这道题目就是把所有数字化成二进制然后建立一颗字典树,
由于si范围是10^9,二进制长度最多为31,我们把每个数字都化成长度为31的二进制,
方便处理。
然后我们统计每个节点的数量。
每次就是删掉trie树中的si,sj,然后把si+sj与trie树中的节点比较。
例如如果该(si+sj)某位是1,我们就在trie树沿着root往下找0,如果有0,继续找,如果没有0,那么该位置取反,
一直找到底即可。
比较完我们要把si,sj重新插入trie树中。
位运算: 1&(x>>i)  判断x某位是0还是1
       x^(1<<i)  将x第i位取反
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<ctime>
#include<string>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#include<set>
#include<map>
#include<cstdio>
#include<limits.h>
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define mes(x, m) memset(x, m, sizeof(x))
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define INF 1e9+7
#define inf 0x3f3f3f3f
#define Pi 4.0*atan(1.0)

#define lowbit(x) (x&(-x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-9;
const int maxn = 1000*30+10;
using namespace std;

inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}

struct trie{
    int next[maxn][2],cot[maxn],tot,rt;
    int creatNode(){
        for(int i=0;i<2;++i){
            next[tot][i]=-1;
            cot[next[tot][i]]=0;
        }
        ++tot;
        return tot-1;
    }
    void init(){
        tot=0;
        rt=creatNode();
    }
    void insert(int x){
        int cur=rt;
        for(int i=30;i>=0;--i){
            int c=1&(x>>i);
            if(next[cur][c]==-1){
                next[cur][c]=creatNode();
            }
            cur=next[cur][c];
            ++cot[cur];
        }
    }
    void del(int x){
        int cur=rt;
        for(int i=30;i>=0;--i){
            int c=1&(x>>i);
            cur=next[cur][c];
            --cot[cur];
        }
    }
    int query(int x){
        int cur=rt;
        for(int i=30;i>=0;--i){
            int c=1&(x>>i);
            if(1==c){
                if(next[cur][0]!=-1&&cot[next[cur][0]]){
                    cur=next[cur][0];
                }else{
                    cur=next[cur][1];
                    x^=(1<<i);
                }
            }else{
                if(next[cur][1]!=-1&&cot[next[cur][1]]){
                    cur=next[cur][1];
                    x^=(1<<i);
                }else{
                    cur=next[cur][0];
                }
            }
        }
        return x;
    }
};
int num[1001];
trie tre;
int main(){
    //freopen("/home/ostreambaba/文档/input.txt", "r", stdin);
    //freopen("/home/ostreambaba/文档/output.txt", "w", stdout);
    int t=read();
    while(t--){
        mes(tre.next,-1);
        mes(tre.cot,0);
        tre.init();
        int n=read();
        int ans=0;
        for(int i=0;i<n;++i){
            num[i]=read();
            tre.insert(num[i]);
        }
        for(int i=0;i<n;++i){
            tre.del(num[i]);
            for(int j=i+1;j<n;++j){
                tre.del(num[j]);
                ans=max(ans,tre.query(num[i]+num[j]));
                tre.insert(num[j]);
            }
            tre.insert(num[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/viscu/article/details/70036623
今日推荐