AcWing 143 最大异或对 (Trie)

题目链接:https://www.acwing.com/problem/content/145/

把每个整数看成长度为 (32) 位的 (01) 串,插入(trie)树,
根据异或运算的性质,要得到最大的异或值,那每次要尽量沿着与当前数字相反的方向走

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;

const int maxn = 3000010;

int n;
int root = 0, cnt = 0, ans = 0;

struct Trie{
	int son[2];
}trie[maxn];

void insert(int x){
	int pos = root;
	for(int i=31;i>=0;--i){
		int num = ((x>>i) & 1);
		if(!trie[pos].son[num]) trie[pos].son[num] = ++cnt; 
		pos = trie[pos].son[num];
	}
}

int query(int x){
	int res = 0;
	int pos = root;
	for(int i=31;i>=0;--i){
		int num = ((x>>i) & 1);
		if(trie[pos].son[num ^ 1]){
			pos = trie[pos].son[num ^ 1];
			res ^= (1 << i);
		} else {
			pos = trie[pos].son[num];
		}
	}
	return res;
}

ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }

int main(){
	n = read();
	int a;
	
	a = read();
	insert(a);
	
	for(int i=2;i<=n;++i){
		a = read();
		ans = max(ans ,query(a));
		insert(a);
	}
	
	printf("%d
",ans);
	
	return 0;
}
原文地址:https://www.cnblogs.com/tuchen/p/13944511.html