題目連結:http://ybt.ssoier.cn:8088/problem_show.php?pid=1472
題目描述:在給定的 N 個整數中選出兩個進行異或運算,求得到的結果最大是多少。
看到這道題要搞異或,首先想到把它們轉成二進位制。
那用什麼存呢?
這就要用到一個比較NB的演算法——字典樹了。
(對字典樹不太瞭解的可以先看我另一篇部落格——https://www.cnblogs.com/wdrdsahudhisjabshdahuhsh/p/16323517.html)
這就是把一堆整數轉成2進位制數,再存到字典樹裡,並用字典樹查詢最大結果。
(ps:異或就是二進位制中當兩個值不相同時返回1,否則返回0)
上程式碼(有註釋):
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a,trie[4000001][2],tot=0; 4 void in(int a){//轉成二進位制並存入字典樹 5 int root=0,id; 6 for(int i=30;i>=0;i--){//從最高位開始 7 id=(a>>i)&1;//提取a在二進位制中第i位的值 8 if(trie[root][id]==0){ 9 trie[root][id]=++tot; 10 } 11 root=trie[root][id];//字典樹 12 } 13 } 14 int out(int a){ 15 int root=0,id,ans=0; 16 for(int i=30;i>=0;i--){ 17 id=(a>>i)&1; 18 if(trie[root][!id]){//找到不同的值了 19 ans=ans|(1<<i);//加上異或這一位的值 20 root=trie[root][!id];//換節點繼續查 21 }else{ 22 root=trie[root][id];//直接往下走 23 } 24 } 25 return ans; 26 } 27 int main(){ 28 int n,ans=0; 29 cin>>n; 30 while(n--){ 31 cin>>a; 32 in(a); 33 ans=max(ans,out(a));//求最大值 34 } 35 cout<<ans;//完事 36 }