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

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

相关推荐
无限码力20 分钟前
华为OD机试真题2026双机位C卷 C++实现【日志解析】
c++·华为od·华为od机试真题·华为od机考真题·华为od机试真题-日志解析
张李浩7 小时前
Leetcode 054螺旋矩阵 采用方向数组解决
算法·leetcode·矩阵
big_rabbit05028 小时前
[算法][力扣101]对称二叉树
数据结构·算法·leetcode
美好的事情能不能发生在我身上8 小时前
Hot100中的:贪心专题
java·数据结构·算法
myloveasuka8 小时前
Java与C++多态访问成员变量/方法 对比
java·开发语言·c++
2301_821700538 小时前
C++编译期多态实现
开发语言·c++·算法
奥地利落榜美术生灬9 小时前
c++ 锁相关(mutex 等)
开发语言·c++
xixihaha13249 小时前
C++与FPGA协同设计
开发语言·c++·算法
小小怪7509 小时前
C++中的函数式编程
开发语言·c++·算法
xixixiLucky9 小时前
编程入门算法题---小明爬楼梯求爬n层台阶一共多少种方法
算法