字典树经典问题

 HDU4852 Xor Sum  字典树

题意

Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大,输出K(共有t组样例,(T < 10),N,M(<1=N,M<=100000))

分析

将每个数插入到线段树后,对于每个s贪心的在字典树上走走即可

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5+10;

int tot;
ll o;
int nt[32*maxn][2];
int cnt[32*maxn];
int a[maxn];
int n;

int newnode()
{
    ++tot;
    memset(nt[tot],0,sizeof(nt[tot]));
    return tot;
}

void Insert(int rt, ll k)
{
    for(int i=32;i>=0;i--)
    {
        if(!nt[rt][(k>>i)&1]){
            int ans=newnode();
            nt[rt][(k>>i)&1]=ans;
            rt=ans;
        }
        else
        {
            rt=nt[rt][(k>>i)&1];
        }
    }
}

ll  query(int rt, ll k)
{
   // int sum=0;
    o=0;
    for(int i=32;i>=0;i--){
        if(((k>>i)&1)==1){
            if(nt[rt][0])
            {
                rt=nt[rt][0];
            }
            else {
                rt=nt[rt][1];
                o+=(1ll<<i);

            }
        }
        else{
            if(nt[rt][1]){
                o+=(1ll<<i);
                rt=nt[rt][1];

            }
            else{
                rt=nt[rt][0];
            }
        }
    }
    return o;
}

int main()
{
   int t;
   scanf("%d", &t);
   int m;
   int pp=1;
   while(t--)
   {
       tot=0;
       memset(nt[0], 0 ,sizeof(nt[0]));
       scanf("%d%d", &n, &m);
       for(int i=0;i<n;i++)
       {
           int x;
           scanf("%d", &x);
           Insert(0, x);
       }
       printf("Case #%d:
", pp++);
       while(m--)
       {
           int q;
           scanf("%d", &q);
           printf("%lld
",query(0,q) );
       }
   }
   return 0;
}
View Code

来源不明

题意

给n个数,从中取两个数,问xor的最大值(1<=1e5)

分析

将n个数插入到字典树中,贪心的在上面走走即可

原文地址:https://www.cnblogs.com/Superwalker/p/8510666.html