zoukankan      html  css  js  c++  java
  • HDU 4825(01 Trie树)

    传送门:

    Xor Sum

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
    Total Submission(s): 3926    Accepted Submission(s): 1724


    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
    23 23 4 5154 14 6 5 63
     

    Sample Output
    Case #1:43Case #2:4
     

    Source
     

        题目描述:给你n个数,m个询问,每个询问给予一个数x,问在n个数中,能与数x组成的异或是最大的数。
        题目分析:最开始看到这道题时,看到数据范围:n,m都是都是1e5的范围,直接枚举的话必定是会超时的。因此,这个题必须得想一种另类的方法。

        因此我们发现,这道题上,因为所有的数都是在2^32的范围内,而最后题目要求的是xor,因此我们可以往位运算上考虑。
        因此我们可以把目标数上的每个数转化为32位的二进制数(不够位补0),并把这些数加入到Trie树上。最后对于所要求的树x,我们可以每次贪心的获取与当前节点数字(0或1)相反的结点,(如果没有则选相同的),最后返回这一个树的id即可。
        总结:这是我做的第一道很有意思的01字典树的问题。(他教育了我字典树不单单只能用在字符串上(つ﹏⊂),还可以用在位运算中。通过记录二级制位的0、1位可以对xor操作(甚至or,&,|....等位运算)进行高效的处理!!很骚的操作!~

          
        
    #include <bits/stdc++.h>
    #define maxn 5000005
    using namespace std;
    typedef long long ll;
    ll a[maxn];
    struct Trie{
        int num;
        int trie[maxn][2];
        int id[maxn];
        void init(){
            memset(trie,0,sizeof(trie));
            memset(id,0,sizeof(id));
            num=1;
        }
        void Insert(ll a,int ids){
            int index=0;
            for(int i=32;i>=0;i--){
                int x=(a&(1ll<<i))>0;
                if(trie[index][x]==0) trie[index][x]=num++;
                index=trie[index][x];
            }
            id[index]=ids;
        }
        int Search(ll a){
            int index=0;
            for(int i=32;i>=0;i--){
                int x=(a&(1ll<<i))>0;
                if(trie[index][!x]!=0){
                    index=trie[index][!x];
                }
                else index=trie[index][x];
            }
            return id[index];
        }
    }tree;
    int main()
    {
        //freopen("in.txt","r",stdin);
        int t;
        scanf("%d",&t);
        int cnt=0;
        while(t--){
            int n,m;
            scanf("%d%d",&n,&m);
            tree.init();
            printf("Case #%d:
    ",++cnt);
            for(int i=0;i<n;i++){
                scanf("%lld",&a[i]);
                tree.Insert(a[i],i);
            }
            while(m--){
                ll tmp;
                scanf("%lld",&tmp);
                int index=tree.Search(tmp);
                printf("%lld
    ",a[tree.Search(tmp)]);
            }
        }
        return 0;
    }
    

  • 相关阅读:
    SSH连接linux的centos报The host '192.168.*.*' is unreachable
    页面格式化数值
    学习webservice之cxf(8):Spring整合CXF
    学习webservice之cxf(7):cxf自定义拦截器
    学习webservice之cxf(6):cxf内置拦截器
    学习webservice之cxf(5):cxf处理map等复杂类型
    学习webservice之cxf(4):cxf处理javabean以及复合类型
    学习webservice之cxf(3):使用webservice实现客户端
    学习webservice之cxf(1):使用cxf实现webservice(使用jdk1.8)
    学习webservice之cxf(2):使用java代码使用webservice(jdk1.8无法使用)
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007306.html
Copyright © 2011-2022 走看看