[HDU] 4825 (01字典树)

Problem Description

Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?


Input

输入包含若干组测试数据,每组测试数据包含若干行。
输入的第一行是一个整数T(T < 10),表示共有T组数据。
每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。


Output

对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
对于每个询问,输出一个正整数K,使得K与S异或值最大。


Sample Input

2
3 2
3 4 5
1
5
4 1
4 6 5 6
3


Sample Output

Case #1:
4
3
Case #2:
4


Source

2014年百度之星程序设计大赛 - 资格赛

Solution

本蒟蒻的第一道 01字典树的题目,算是了解了这个数据结构.

1) 插入
操作如平常的 Tire 树,每次都通过这个树的二进制下位来确定位置.
同时另开一个数组表示节点.再最后打一个标记大小.

2) 查询
每一次只要找和自己这一位不同的即可,如果有,那么就继续沿着走,否则就走相同的. 如果已经没有路可走了,那么直接返回值.

然后对着别人板子打了一波,代码如下.

代码

//HDU 4825
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 5;        
typedef long long ll;
ll c[maxn],n,m;
int ch[32 * maxn][2];             
ll value[32 * maxn];                
int node_cnt;                       

inline void init()  //将整个数组清零
{                 
    node_cnt = 1;
    memset(ch[0],0,sizeof(ch));
}           

inline void insert(ll x){           
                                    
    int cur = 0;
    for(int i = 32;i >= 0;--i){
        int idx = (x >> i) & 1;
        if(!ch[cur][idx]){
            memset(ch[node_cnt],0,sizeof(ch[node_cnt]));
            ch[cur][idx] = node_cnt;
            value[node_cnt++] = 0;
        }
            cur = ch[cur][idx];
        }
        value[cur] = x;           
}

inline ll query(ll x){              
    int cur = 0;
    for(int i = 32;i >= 0;--i){
        int idx = (x >> i) & 1;
        if(ch[cur][idx ^ 1]) cur = ch[cur][idx ^ 1];
        else cur = ch[cur][idx];
    }
    return value[cur];
}

int main()
{
    int t; scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        init();
        scanf("%lld%lld",&n,&m);
        for(int j=1;j<=n;j++)
        {scanf("%lld",&c[j]); insert(c[j]);}
        cout<<"Case"<<' '<<'#'<<i<<':'<<endl;
        while(m--)
        {
            int x; scanf("%d",&x);
            cout<<query(x)<<endl;
        }
    }
} 

猜你喜欢

转载自www.cnblogs.com/Kv-Stalin/p/9215650.html