zoukankan      html  css  js  c++  java
  • HDU 4825 Xor Sum (模板题)【01字典树】

    <题目链接>

    题目大意:

    给定n个数,进行m次查找,每次查找输出n个数中与给定数异或结果最大的数。

    解题分析:

    01字典树模板题,01字典树在求解异或问题上十分高效。利用给定数据的二进制数进行建树,然后在查找的时候,利用贪心的策略,优先寻找与当前位数的0、1值不同的路线,从而达到异或值最大的目的。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 1e5+5;
    int n,m,pos;
    ll val[N*32],nxt[N*32][2];
    
    void init(){
        pos=1;
        memset(nxt,0,sizeof(nxt));
        memset(val,0,sizeof(val));
    }
    void Insert(ll x){    //用x的二进制建树
        int now=1;
        for(int i=32;i>=0;i--){     
            int to=(x>>i)&1;     //从最高位开始建
            if(!nxt[now][to])nxt[now][to]=++pos;
            now=nxt[now][to];
        }
        val[now]=x;      //标记前缀二进制串为完整的数字
    }
    ll query(ll x){   //寻找01Trie树上异或的最大数
        int now=1;
        for(int i=32;i>=0;i--){
            int to=(x>>i)&1;
            if(nxt[now][to^1])now=nxt[now][to^1];   //优先找与当前位不同的路线
            else now=nxt[now][to];    //如果没有的话,只能找相同的
        }
        return val[now];
    }
    int main(){
        int ncase=0;
        int T;scanf("%d",&T);while(T--){
            init();
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){
                ll cur;scanf("%lld",&cur);
                Insert(cur);
            }
            printf("Case #%d:
    ",++ncase);
            for(int i=1;i<=m;i++){
                ll cur;scanf("%lld",&cur);
                printf("%lld
    ",query(cur));
            }
        }
    }

    2019-03-02

  • 相关阅读:
    文件IO学习
    简单哈希表学习
    关于二叉树的遍历
    关于多点共线问题
    关于线程
    时间复杂度O()与KMP算法
    单链表相关
    拷贝构造函数与深浅拷贝
    在windows把python写成bat文件的坑
    python学习手册:第二十五章——oop
  • 原文地址:https://www.cnblogs.com/00isok/p/10460028.html
Copyright © 2011-2022 走看看