AcWing 143 最大異或對

2021-09-24 02:39:03 字數 1122 閱讀 8633

題目描述:

在給定的n個整數a1,a2……an中選出兩個進行xor(異或)運算,得到的結果最大是多少?

輸入格式

第一行輸入乙個整數n。第二行輸入n個整數a1~an。

輸出格式

輸出乙個整數表示答案。

資料範圍

1≤n≤10^5,0≤ai<2^31

輸入樣例:

3

1 2 3

輸出樣例:

3
分析:

本題要求我們從n個數中找出兩個數來進行異或,並輸出異或後的最大結果。暴力的做法就是兩層迴圈來列舉進行異或的兩個數,時間複雜度為平方級別的,而n的大小是10w,所以會超時。考慮對於乙個數x而言,是否有辦法在其他數中快速找出與之異或值最大的那個數而不用遍歷所有數去找到呢?

我們知道,對於異或運算,需要相同位置的數不同最後異或得到的數才為1,即0 ^ 1 = 1。對於乙個int型別的正整數,除去符號位以外,剩下31位數與它都相反最後異或的結果才是最大的。於是將n個數構建出一顆字典樹,形狀為二叉樹。例如01001100(以8位為例,實際要考慮的是31位數),最高位為0,首先判斷字典樹上該層次結點有沒有為1的,有則沿著1往下繼續遍歷,每次遍歷都盡可能的走與原位置數相反的路徑(沒有相反的就走相同的),最後到達葉子結點時,得到的數也就是異或能得到的最大的數了,當然,需要我們在遍歷的同時記錄下對應位置異或的結果,這樣最後只需要一重迴圈即可解決問題了。

#include #include using namespace std;

const int maxn = 100005,maxm = 3000000;

int n;

int a[maxn],son[maxm][2],idx;

void insert(int x)

}int search(int x)

else p = son[p][s];

}return res;

}int main()

int ans = 0;

for(int i = 0;i < n;i++) ans = max(ans,search(a[i]));

cout

}

Acwing143 最大異或對

用乙個tire樹來存下n個數的二進位制形式的01串,串的長度是31,因為每個數最多為2 31所以,取31,然後根據異或的特性,列舉一下所有的數,取這個數的反碼,去樹中尋找盡可能和反碼向同的路徑,並且記錄下路徑過程的異或值即可 include include include using namespa...

acwing 143 最大異或對

題面 在給定的n個整數a1,a2 an a1,a2 an a1,a2 an中選出兩個進行xor 異或 運算,得到的結果最大是多少?輸入格式 第一行輸入乙個整數n。第二行輸入n個整數a 1 a1 a1 a n an an。輸出格式 輸出乙個整數表示答案。資料範圍1 n 105 1 n 105 1 n ...

Acwing143 最大異或對

在給定的n個整數a1,a2 an a1,a2 an a1,a2 an中選出兩個進行xor 異或 運算,得到的結果最大是多少?輸入格式 第一行輸入乙個整數n。第二行輸入n個整數a 1 a1 a1 a n an an。輸出格式 輸出乙個整數表示答案。資料範圍1 n 105 1 n 105 1 n 105...