1. 程式人生 > 其它 >#LOJ 10050 The XOR Largest Pair

#LOJ 10050 The XOR Largest Pair

#10050. 「一本通 2.3 例 2」The XOR Largest Pair

又是搋樹。

看到這一題,首先想到的 \(\mathcal{O(n^2)}\) 的暴力,一看範圍 \(1e5\) 果斷放棄。

想想正解怎麼做(我也借鑑了別人的思路,畢竟第一次學

根據 \(\oplus\) 的性質,相同為 \(1\),不同為 \(0\),也就是說,把數拆成二進位制,越高位不一樣 \(\oplus\) 出來的數越大,利用搋樹,此時搋樹是個二叉樹,我們以二進位制最高位為根建立搋樹,因為這樣能把路徑上的值按照二進位制轉十進位制的方法求出來,因為高位不一樣越大,和線段樹進左右子樹一樣。

/*
Knowledge : Rubbish Algorithm
Work by :Gym_nastics
Time : O(AC)
*/
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
const int Mod=1e9+7;
const int N=1e6+6;

int read() {
    int x=0,f=0;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
    for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch&15);
    return f?-x:x;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) print(x/10);
    putchar(x%10+48);
}

int Trie[N][2],tot;

void Insert(int x){
    int pos=0;
    for(int i=31;i>=0;i--){
        int w=(x>>i)&1;
        if(!Trie[pos][w]) Trie[pos][w]=++tot;
        pos=Trie[pos][w];
    }
}

int Query(int x){
    int res=0,pos=0;
    for(int i=31;i>=0;i--){
        int w=(((x>>i)&1)^1);
        if(Trie[pos][w]) res=res<<1|1,pos=Trie[pos][w];
        else res<<=1,pos=Trie[pos][w^1];
    }return res;
}

signed main() {
   int n=read(),Ans=-INF;
   for(int i=1;i<=n;i++){
       int x=read();Insert(x);               
       Ans=max(Ans,Query(x));
   }print(Ans);
   return 0;
}