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

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

相关推荐
net3m3335 分钟前
一阶软件低通滤波器算法
人工智能·算法
王老师青少年编程37 分钟前
信奥赛C++提高组csp-s之搜索进阶(记忆化搜索案例实践3)
c++·记忆化搜索·方格取数·csp·信奥赛·csp-s·提高组
水木流年追梦1 小时前
大模型入门-大模型优化方法12-YaRN 长文本外推技术
人工智能·分布式·算法·正则表达式·prompt
J-Tony111 小时前
【JVM】三色标记法
java·jvm·算法
wengad1 小时前
机器学习实践理论基础|算法、模型和数据集
人工智能·算法·机器学习
Titan20242 小时前
Linux动静态库
linux·服务器·c++
j_xxx404_2 小时前
MySQL表操作硬核解析:从 CREATE TABLE 到磁盘文件、ALTER TABLE 与 DDL 风险
运维·服务器·数据库·c++·mysql·adb·ai
wuminyu3 小时前
Java锁机制之park和unpark源码剖析
java·linux·c语言·jvm·c++
梦梦代码精3 小时前
为什么这个开源的AI平台会火?有点东西。。。
人工智能·算法·机器学习·docker·开源
随意起个昵称3 小时前
线性dp-综合刷题1(Not Alone)
算法·动态规划