zoukankan      html  css  js  c++  java
  • AcWing 143. 最大异或对 01字典树打卡

    在给定的N个整数A1A2ANA1,A2……AN中选出两个进行xor(异或)运算,得到的结果最大是多少?

    输入格式

    第一行输入一个整数N。

    第二行输入N个整数A1A1~ANAN。

    输出格式

    输出一个整数表示答案。

    数据范围

    1N1051≤N≤105,
    0Ai<2310≤Ai<231

    输入样例:

    3
    1 2 3
    

    输出样例:

    3


    题意:让你求一对数,他们的异或值最大
    思路:首先暴力肯定不行,1e5的范围,我们想想贪心高数位可不可以,我们为了保证异或值最大,肯定是从高位开始保留起,但是确实是要从高位开始找,但是我们这样不好查找
    前面说了Trie是一个高效的查找数据结构,我们建立一个Trie,每插入一个节点我们就查找前面所有的,这样能查找到所有情况,因为我们是要查找最大异或,肯定是走与当前数字
    相反的那一条路线,如果实在是另一条没有路,我们就只能走那条了,然后计算从上而下的计算值是多少
    !叶子节点是二进制最低位,为什么呢,因为我们是要贪心从高位开始取,而我们字典树是从一开始就避免相同,所以正好与我们贪心取高位相吻合,所以必须按这个插入顺序


    #include<bits/stdc++.h>
    #define maxn 100005
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    ll n,top;
    ll a[maxn];
    ll tree[maxn*32][2];
    void insert(ll x){
        ll root=0;
        for(int i=0;i<32;i++){
            ll z=(x>>(31-i))&1;
            if(!tree[root][z]) tree[root][z]=++top;
            root=tree[root][z];
        } 
    }
    ll query(ll x){
        ll root=0;
        ll sum=0;
        for(int i=0;i<32;i++){
            ll z=(x>>(31-i))&1;
            if(tree[root][!z]){
                sum+=1<<(31-i);
                root=tree[root][!z];
            }
            else{
                root=tree[root][z];
            }
        }
        return sum;
    }
    int main(){
        scanf("%lld",&n);
        ll mx=0,x;
        for(int i=0;i<n;i++){
            scanf("%lld",&x);
            mx=max(mx,query(x)); 
            insert(x);
        }
        printf("%lld",mx);
    } 
     
  • 相关阅读:
    Java匹马行天下之JavaSE核心技术——工具类
    微信小程序
    在express3里用ejs模版引擎时,如何使其支持'.html'后缀
    node
    webstorm常用快捷键
    Meta标签中的format-detection属性及含义
    使用console进行 性能测试 和 计算代码运行时间
    JS获取浏览器URL中查询字符串的参数
    jspm 简介
    vue2.0 keep-alive最佳实践
  • 原文地址:https://www.cnblogs.com/Lis-/p/10896647.html
Copyright © 2011-2022 走看看