題解0014:信奧一本通1472——The XOR Largest Pair(字典樹)

uf0_金幣灰黃^w.h發表於2022-06-05

題目連結: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 }

相關文章