AcWing 143. 最大異或對
阿新 • • 發佈:2020-06-01
AcWing 143.最大異或對
題目描述
在給定的N個整數A1,A2……AN中選出兩個進行xor(異或)運算,得到的結果最大是多少?
輸入格式
第一行輸入一個整數N。
第二行輸入N個整數A1~AN。
輸出格式
輸出一個整數表示答案。
資料範圍
1≤N≤10^5,
0≤Ai<2^31
輸入樣例:
3
1 2 3
輸出樣例:
3
思路
先想一下暴力的做法,然後優化
int arr[N]; int ans = 0; for(int i = 0; i < n; ++i){ for(int j = 0; j < i; ++j) ans = (ans,arr[i] ^ arr[j]); }
顯然上述的暴力方式時間複雜度為O(n ^ 2),明顯會超時,這樣就要想著如何優化,這裡我們可以優化內層迴圈:採用trie樹來優化
我們每次把每一個數的二進位制的沒一個位儲存到trie樹中,這樣每一個葉子節點就是代表了一個數
每輸入一個x,先插入樹中,我們從最高位開始與樹中的資料匹配,如果存在與x在同一位置二進位制位相反的數那麼就選擇樹中的這樣的點(就相當於把已經插入的數分成了兩個集合...),如果不存在就選自己。如下所示
程式碼實現
#include <iostream> #include <algorithm> using namespace std; const int N = 100010; int s[N * 32][2],ans = 0,idx = 0; void insert(int x){ int p = 0; for(int i = 30; i>=0; --i){ int ch = x >> i & 1; if(s[p][ch] == 0) s[p][ch] = ++ idx; p = s[p][ch]; } } int search(int x){//當前的數和已經插入的樹中的數,找異或最大值 int p = 0,ans = 0; for(int i = 30; i >= 0; --i){ int ch = x >> i & 1; if(s[p][!ch]){ p = s[p][!ch]; ans = ans * 2 + !ch; } else{ p = s[p][ch]; ans = ans * 2 + ch; } } return ans; } int main(){ int n;cin >> n; while(n --){ int x; cin >>x; insert(x); ans = max(ans,x ^ search(x)); } cout << ans << endl; return 0; }