算法模板-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

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

相关推荐
晴天的雨.9929 分钟前
【C++算法】和为s的两个数
开发语言·数据结构·c++·算法
aramae7 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
荆棘鸟智能7 小时前
城市感知设备怎么统一接入?从多协议网关到设备模型的中间件架构设计
人工智能·算法·边缘计算
知识分享小能手10 小时前
C++ 学习教程,从入门到精通,C++ 入门知识 — 完整知识点(1)
开发语言·c++·学习
qq_1998868711 小时前
第8板块·第2节:统一内存的高级特性与性能调优
c++·人工智能·gpu算力·cuda
INGNIGHT11 小时前
270 · 电话号码的字母组合II(Trie)
linux·算法
2401_8390805412 小时前
C++常见八股
数据结构·c++·算法
qq_1998868712 小时前
第6板块 第2节 CUDA运行时API与驱动API 核心笔记
c++·人工智能·gpu算力
青山是哪个青山12 小时前
LeetCode 188:买卖股票的最佳时机 IV
算法
mikuyyds12 小时前
geo-toolbox 插件算法解析:RUSLE 与 MUSLE 的工程化落地
算法·rust·gis