HDU5536 Chip Factory(Trie树,二进制)

本文探讨了一种CPU芯片管理场景下的数学问题,即在给定的芯片串号集合中找到三个不同的芯片,使得两颗芯片的串号之和与第三颗芯片串号进行异或操作的结果最大。通过使用字典树数据结构优化搜索过程,实现高效的算法解决方案。

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

2
3
1 2 3
3
100 200 300

Sample Output

6
400

思路

先说题意,给出一堆数,然后从这些数中找出两个数,求和,然后求出这个和异或另一个数的最大值,假设把这些数存在了数组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 long
using 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;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值