【维护异或和】 最大异或对

传送门

题意

给定(N)个整数(A_{1}、A_{2}、dots A_{n}),从中选出两个进行异或运算求最大值

数据范围

(egin{array}{l}1 leq N leq 10^{5} \ 0 leq A_{i}<2^{31}end{array})

题解

将数字的二进制(01)串作为字符串建立字典树,建立长度为(30)(01)字符串,每次查询时,贪心的从高位开始,
每次都将与当前的二进制位不同的计算代表的二进制数字,累加即此数字能够得到的最大值
字典树的长度为(10^{5} imes 30) ,在极端情况下每个数字的二进制都不同,每一个数字的二进制有(30)

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)

const int N=1e5+10;
int trie[N*30][2],tot=1;

void insert(int x)
{  
    int p=1;
    per(i,0,31)
    {
        int u=x>>i&1;
        if(!trie[p][u]) trie[p][u]=++tot;
        p=trie[p][u];
    }
}
int query(int x)
{
    int p=1;
    int res=0;
    per(i,0,31)
    {
        int u=x>>i&1;
        if(trie[p][!u]) 
        {
            res+=1<<i;
            p=trie[p][!u];
        }
        else p=trie[p][u];
    }
    return res;
}
void solve()
{
    int n;
    cin>>n;
    int ans=-1e6;
    rep(i,0,n)
    {
        int x;
        cin>>x;
        insert(x);
        ans=max(ans,query(x));
    }
    cout<<ans<<endl;
}

int main()
{
    solve();
}
原文地址:https://www.cnblogs.com/hhyx/p/13388996.html