1. 程式人生 > >Trie樹_CH1602_The XOR Largest Pair

Trie樹_CH1602_The XOR Largest Pair

點此開啟題目頁面

思路分析:

    易知, 題目等價於計算i, j, 其中i, j滿足1 =< i < j <= N且A_{i}異或A_{j}最大, 對於任意的2 <= x <= N, 考慮計算使得1 <= y < x且A_{x}異或A_{y}最大的A_{x}異或A_{y}的值, 可將A_{1}...A_{x - 1}插入一個只含有字元'0'和'1'的Tire樹T中, 其中每個A_{i}對應一個31位的二進串, 最高位對應字串起始字元. 接下來以A_{y}對應的二進位制串為依據, 從T的根, 儘量選擇與當前A_{x}對應字元('0'或'1'相異的分支), 直至到達葉結點, 此葉結點對應的二進位制串即為A_{y}. 下面給出AC程式碼, 易知, 下述程式的時間複雜度為O(31N).

//CH1602_The XOR Largest Pair
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAX = 31e5 + 5, NIL = (1ll << 31) - 1;
int trie[MAX][2], tot;
int main(){
	int ans = -NIL, N; scanf("%d", &N);
	for(int i = 1; i <= N; ++i){
		int tans = 0, k = 0, t; scanf("%d", &t);
		for(int j = 30; j >= 0; --j){
			int b = t >> j & 1;
			if(trie[k][!b]) k = trie[k][!b], tans |= 1 << j;
			else k = trie[k][b];
		}
		ans = max(ans, tans);
		//將t插入trie中
		k = 0;
		for(int j = 30; j >= 0; --j){
			int b = t >> j & 1;
			if(!trie[k][b]) trie[k][b] = ++tot;
			k = trie[k][b];
		} 
	}
	printf("%d\n", ans);	
}