【Trie】最大異或對
阿新 • • 發佈:2021-10-20
【題目描述】
在給定的N個整數A1,A2……AN中選出兩個進行xor(異或)運算,得到的結果最大是多少?
輸入格式
第一行輸入一個整數N。
第二行輸入N個整數A1~AN。
輸出格式
輸出一個整數表示答案。
資料範圍
1≤N≤105,
0≤Ai<231
輸入樣例:
3
1 2 3
輸出樣例:
3
①利用Trie優化,將所有數字按位從高到低位存入Trie樹中,由於要計算最大異或對,那麼對於一個數字num,能夠與其得出最大異或值得數字一定是每一位都與num相反的。
那麼就取num的每一位與Trie樹中的數字進行查詢,如果能夠找到相反的位,就繼續往下,找不到也繼續往下查詢。
②最大的數字是二進位制32位的,那麼就將所有數字都統一視為32位的,免去判斷的麻煩,只有走完走到了葉子結點才算是一個數字。
1 #include <iostream> 2 using namespace std; 3 const int N = 31 * 100009; 4 int Trie[N][2],idx; 5 void insert(int num) 6 { 7 int p = 0; 8 for(int i = 30;i >= 0;--i) 9 { 10 int u = (num >> i) & 1; 11 if(!Trie[p][u]) 12 Trie[p][u] = ++idx;13 p = Trie[p][u]; 14 } 15 } 16 17 int query(int num) 18 { 19 int p = 0,res = 0; 20 for(int i = 30;i >= 0;--i) 21 { 22 int u = num >> i & 1; 23 if(Trie[p][!u]) 24 { 25 res = (res << 1) + !u; // 注意:加號運算子優先順序高於<< 26 p = Trie[p][!u];27 } 28 else 29 { 30 res = (res << 1) + u; 31 p = Trie[p][u]; 32 } 33 } 34 return num ^ res; 35 } 36 37 int n,res; 38 int main() 39 { 40 cin >> n; 41 while(n--) 42 { 43 int num; 44 cin >> num; 45 insert(num); 46 res = max(res,query(num)); 47 } 48 cout << res << endl; 49 return 0; 50 }