HDU 4825 Xor Sum(字典树 经典应用,求一个数与其他数xor最大)

题目链接

求xor值是字典树的一个经典的应用,首先我们把数用二进制表示,然后存在字典树里面,从高位到低位的存,然后查找的时候我们走不同的边(这样xor的结果会是1),如果没有不同边,那就走这个相同的边好了。

题意:给你n个数,然后再给你m询问,每次询问是找到n个数里面与这个数的xor最大的那个数。
解法:xor就可以想到用字典树了,把数拆分为二进制,然后建立字典树,接着在字典树上跑。


#include<cstdio>
#include<algorithm>
#include<cstring>
//#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=4000005;
const LL inf=1LL<<45;
const LL mod=1e9+7;

struct Tree{
    int Next[maxn][2];//Next[i][j]表示i的儿子节点j在树里面编号
    LL End[maxn];//以编号i结束的叶子节点对应的值。
    int root,L;

    int newNode(){
        cl(Next[L],-1);
        End[L]=0;
        return L++;
    }
    void init(){
        L=0;
        root=newNode();
    }
    void Insert(LL x){
        int now=root;
        for(int i=32;i>=0;i--){
            int v=(x&(1LL<<i))?1:0;
            if(Next[now][v]==-1){
                Next[now][v]=newNode();
            }
            now=Next[now][v];
        }
        End[now]=x;
    }
    LL query(LL x){
        int now=root;
        for(int i=32;i>=0;i--){
            int v=(x&(1LL<<i))?1:0;
            if(Next[now][!v]!=-1){
                now=Next[now][!v];
            }
            else {
                now=Next[now][v];
            }
        }
        return End[now];
    }
};
Tree tree;
int main(){
    int T;scanf("%d",&T);int cas=1;
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);

        tree.init();
        for(int i=0;i<n;i++){
            LL x;scanf("%lld",&x);
            tree.Insert(x);
        }
        printf("Case #%d:\n",cas++);
        while(m--){
            LL x;scanf("%lld",&x);
            printf("%lld\n",tree.query(x));
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值