hdu 5563 Chip Factory(字典树)

Chip Factory

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



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
  
  
2 3 1 2 3 3 100 200 300
 

Sample Output
  
  
6 400
 

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

题意描述:给你一串序列,选出三个不同下标的数,使得其中两个数的和与第三个数的异或值最大。

思路分析:典型的字典树,对每个数建一颗字典树,并记录这个数的下标位置。再枚举任意两个数的和进行匹配就好,贪心的求最大值。
注意点:
1. 建树的时候每个数看做有31位的二进制,从最高位开始建树。
2. 根据建树,要清楚的判断终止条件。
代码:
#include <bits/stdc++.h>

using namespace std;
const int maxn=500000;
int cnt;
vector<int> End[maxn];
int next1[maxn][3];
int root;
int a[maxn];
int res;
int xx,yy;
int newnode()
{
    next1[cnt][0]=next1[cnt][1]=0;
    End[cnt].clear();
    cnt++;
    return cnt-1;
}
void ini()
{
    cnt=1;
    root=newnode();
}
int low(int x,int i)
{
    return (x>>i)&1;
}
void Ins(int x,int id)
{
    int now=root;
    for(int i=30;i>=0;i--)
    {
        if(next1[now][low(x,i)]==0)next1[now][low(x,i)]=newnode();
        now=next1[now][low(x,i)];
    }
    End[now].push_back(id);
}
int tra(vector<int> yc,int x)
{
    for(int i=0;i<yc.size();i++)
    {
        if(xx==yc[i]||yy==yc[i]){continue;}
        else
        {
            res=x^a[yc[i]];
            return 1;
        }
    }
    return 0;
}
int dfs(int x,int pos,int fa,int t)
{
    if(fa==0)return 0;
    if(pos==-1)
    {
        if(tra(End[fa],x))return 1;
        else return 0;
    }
    else
    {
        if(dfs(x,pos-1,next1[fa][low(x,pos)^1],0))
        {
            return 1;
        }
        else
        {
            if(dfs(x,pos-1,next1[fa][low(x,pos)],0))return 1;
        }
    }
    return 0;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        ini();
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=0;i<n;i++)
        {
            Ins(a[i],i);
        }
        int ans=0;
        for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
        {
            res=0;
            xx=i,yy=j;
            dfs(a[i]+a[j],30,root,0);
            ans=max(ans,res);

        }//sol(root);

        printf("%d\n",ans);
    }
    return 0;
}


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值