算法模板-01trie数

trie树

在蓝桥杯中我们需要掌握两种trie树:

字符字典树和01trie树,

其中字符字典树主要用于处理单一字符串面向多个字符串的匹配问题

而01trie树主要用于处理异或最大值的相关问题。

字符字典树

01trie树

01trie树由数组实现,其基本构成如下:

cpp 复制代码
int son[32*N][32];
int idx;
//其中son用于存储每个节点的儿子节点的编号,
//idx用于动态创立儿子节点son的第二位坐标为0表示为左儿子,
//第二位坐标为1表示为右儿子。
void insert(long long x){
	int now=0;
	for (int i=31;i>=0;i--){
		int k=(x>>i)&1;
		if (!son[now][k])
			son[now][k]=++idx;
		now=son[now][k];
	}
}


long long query(long long x){
	int now=0;
	long long res=0;
	for (int i=31;i>=0;i--){
		int k=(x>>i)&1;
		if (son[now][!k]){
			res+=(long long )(1)<<i;
			now=son[now][!k];
		}
		else{
			now=son[now][k];
		}
	}
	return res;
}

代码模板

cpp 复制代码
//不记录每个节点度数的写法
#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;
const int N=1e5+7;
long long a[N];
int son[35*N][35];
int n;
int idx;

void insert(long long x){
	int now=0;
	for (int i=31;i>=0;i--){
		int k=(x>>i)&1;
		if (!son[now][k])
			son[now][k]=++idx;
		now=son[now][k];
	}
}

long long query(long long x){
	int now=0;
	long long res=0;
	for (int i=31;i>=0;i--){
		int k=(x>>i)&1;
		if (son[now][!k]){
			res+=(long long )(1)<<i;
			now=son[now][!k];
		}
		else{
			now=son[now][k];
		}
	}
	return res;
}
long long ans=0;
int main(){
	cin>>n;
	for (int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		insert(a[i]);
	}
	for (int i=1;i<=n;i++){
		ans=max(ans,query(a[i]));
	}
	cout<<ans<<endl;
	return 0;
}
cpp 复制代码
//记录每个节点度数的写法
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;

int n;
const int N=1e5+7;
long long a[N];
set<int > f[N];
int idx;
int son[N*35][2];
int degree[N*35];
void build(long long x,int cnt){
	int now=0;
	for (int i=31;i>=0;i--){
		int k=(x>>i)&1;
		if (!son[now][k]){
			son[now][k]=++idx;
		}
		now=son[now][k];
		degree[now]+=cnt;
	}
}

long long query(long long x){
	int now=0;
	long long res=0;
	for (int i=31;i>=0;i--){
		int k=(x>>i)&1;
		if (son[now][!k]&&(degree[son[now][!k]]>0)){
			now=son[now][!k];
			res+=1<<i; 
		}
		else{
			now=son[now][k];
		}
	}
	return res;
}
long long ans;
int main(){
	cin>>n;
	for (int i=0;i<n;i++){
		scanf("%lld",&a[i]);
		build(a[i],1);
	}
	for (int i=0;i<n;i++){
		int x;
		scanf("%d",&x);
		if (x==-1)
			continue;
		f[i].insert(x);
		f[x].insert(i);
	}
	for (int i=0;i<n;i++){
		for (set<int>::iterator j=f[i].begin();j!=f[i].end();j++){
			build(a[*j],-1);
		} 
		long long k=query(a[i]);
		ans=max(ans,k);
		for (set<int>::iterator j=f[i].begin();j!=f[i].end();j++){
			build(a[*j],1);
		}
	}
	cout<<ans<<endl;
	return 0;
}

例题

(1.lgU395507 最大异或对(01Trie))https://www.luogu.com.cn/problem/U395507

该题解答即为上述模板中不记录每个节点度数的写法。

(2.P13874 蓝桥杯 2024 省 Java/Python A 最大异或结点)https://www.luogu.com.cn/problem/P13874

该题解答即为上述模板中记录每个节点度数的写法。

相关推荐
不会就选b2 分钟前
算法日常・每日刷题--<归并排序>1
数据结构·算法
啦啦啦啦啦zzzz28 分钟前
算法:回溯算法
c++·算法·leetcode
IT探索42 分钟前
Linux 查找文件指令总结
linux·算法
Lzg_na1 小时前
订阅发布模块事例
c++
郝学胜-神的一滴1 小时前
[简化版 GAMES 104] 现代游戏引擎 02:拆解现代游戏引擎5+1层级架构,吃透引擎底层核心逻辑
c++·unity·架构·游戏引擎·图形渲染·unreal engine·系统设计
汉克老师1 小时前
2026年CSP-J初赛分数线-----预测
c++·csp-j·小学生·学c++编程
脱胎换骨-军哥1 小时前
C++数据库存储引擎内核开发:B+树索引与MVCC并发控制的完整实现
数据库·c++·b树
Lumos1861 小时前
51单片机从零到实战(完结)——后续学习路线建议
算法
稚南城才子,乌衣巷风流1 小时前
DFS序详解:原理、应用与实现
算法·深度优先·图论