The XOR Largest Pair [Trie]


描述

在給定的N個整數A1,A2……AN中選出兩個進行xor運算,得到的結果最大是多少?

輸入格式

第一行一個整數N,第二行N個整數A1~AN。

輸出格式

一個整數表示答案。

樣例輸入

3
1 2 3

樣例輸出

3

數據范圍與約定

  • 對於100%的數據: N<=\(10^5\), 0<=Ai<\(2^{31}\).

題解

看到\(A_i\)最大為\(2^{31}\)很容易想到把數字拆成一個一個數位存進字典樹,而為了異或值最大,我們可以想到一個貪心,在求一個數字\(A_i\)與另一個數字\(A_j\)最大異或值時,我們要盡量讓它們對應數位上的數字不同,即0對1,1對0.
那么在trie樹檢索的時候,我們就可以盡量往與當前位相反的指針上跑,如果沒有就只能走原來的數位,根據xor運算相同得0,不同為1的運算法則,這樣是可以得到兩個數異或的最大值的
然后在存進數字的時候,我們要倒着存,這要方便后續的檢索中更新答案
綜上所述,我們可以循環i=1~n,對於每個i,前面必定已經有i-1個數字插入進了trie樹,我們每次將答案與檢索得到的答案取個最小值就可以了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b)
#define in(i) (i=read())
using namespace std;
int read() {
    int ans=0,f=1; char i=getchar();
    while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
    while(i>='0' && i<='9') {ans=(ans<<1)+(ans<<3)+i-'0'; i=getchar();}
    return ans*f;
}
int n,m,tot,ans;
int trie[4000010][2],cnt[4000010];
void insert(int x) {
    int p=0;
    for(int i=31;i>=0;i--) {
        int c=(x>>i)&1;
        if(!trie[p][c]) trie[p][c]=++tot;
        p=trie[p][c];
    }
}
int search(int x) {
    int p=0,ans=0;
    for(int i=31;i>=0;i--) {
        int c=(x>>i)&1,o=c^1;
        if(trie[p][o]) p=trie[p][o],ans=ans<<1|1;
        else p=trie[p][c],ans<<=1;
    }
    return ans;
}
int main()
{
    in(n);
    for(int i=1;i<=n;i++) {
        int x; in(x);
        ans=Max(ans,search(x));
        insert(x);
    }
    cout<<ans<<endl;
    return 0;
}

博主蒟蒻,隨意轉載.但必須附上原文鏈接

http://www.cnblogs.com/real-l/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM