Trie树_CH1602_The XOR Largest Pair

版权声明:本文为博主原创作品, 转载请注明出处! https://blog.csdn.net/solider98/article/details/83864338

点此打开题目页面

思路分析:

    易知, 题目等价于计算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);	
}

猜你喜欢

转载自blog.csdn.net/solider98/article/details/83864338
今日推荐