主页/OI/01Trie
2026年5月5日预计 3 分钟阅读OI

01Trie

zbl2012
zbl2012博主 & 创作者

01Trie 是一种基于 Trie字典树 上的数据结构,是一种解决关于异或类问题的数据结构。

01Trie 的本质就是把每个数变成二进制串再放到字典树上,在贪心求解。

把每一个数转化成 3131 位二进制,想让它的异或值最大,那就是让 00 尽量遇到 1111 尽量遇到 00。所以就要从最高位开始,尽可能的让这个数的在二进制下的每一位都与枚举的数不同,如果不能满足,那就相同。 实现就是把每一个数的二进制放在 Trie 上维护,让后直接上模板即可。

貌似有更高端的压位01Trie。学了再补。

时间复杂度 O(nk)O(nk)kk 是个 100\le100 的常数。

注意点 1.要从高位到低位枚举,且枚举 3131 位二进制时注意是到 i0i\ge 0 而不是 i1i\ge 1。 2.sonson 数组的第二位因为是存二进制,所以只用开 55 就够了。

code

cpp
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10;
int son[N][5];
int cnt[N],idx;
void insert(int x){
	int p=0;
	for(int i=31;i>=0;i--){	
		int u=(x>>i)&1;
		if(!son[p][u])son[p][u]=++idx;
		p=son[p][u];
	}
	cnt[p]++;
}
int query(int x){
	int p=0;
	int res=0;
	for(int i=31;i>=0;i--){
		int u=(x>>i)&1;
		if(son[p][1^u])res=res^(1<<i),p=son[p][1^u];
		else p=son[p][u];
	}
	return res;
}
int n,a[N];
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		insert(a[i]);
	}
	int mx=-1e9;
	for(int i=1;i<=n;i++)mx=max(mx,query(a[i]));
	cout<<mx;
	return 0;
}

文章留言区

已有 0 条精彩探讨

正在拼命加载留言中...

发表您的见解

※ 提倡客观理性讨论。留言需要经过安全核查,请勿注入恶意链接。
上一篇文章并查集下一篇文章 字符串hash