Trie树

Tomfng Lv1

Trie树(又叫前缀树字典树)是一种树形结构,专门用于高效地存储和查找字符串集合,特别适合处理前缀相关问题,如自动补全、字符串匹配、前缀计数等。

代码模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//以最经典的字符串为例
//一般是要么全是大写要么全是小写,就可以轻松映射到26个数字之中
int son[N][N],cnt[N],idx;
// 0号点既是根节点,又是空节点
// son[][]存储树中每个节点的子节点
// cnt[]存储以每个节点结尾的单词数量

//插入操作
void insert(const char *str)
{
int p=0;//从根节点开始
for(int i=0;str[i];i++)
{
int u=str[i]-'a';//映射为数字
if(!son[p][u])son[p][u]=++idx;//如果不存在当前字符,就插入。注意要保留根节点的0
p=son[p][u];
}
cnt[p]++;
}
//查询操作
int query(const char *str)
{
int p=0;
for(int i=0;str[i];i++)
{
int u=str[i]-'a';
if(!son[p][u])return 0;
p=son[p][u];
}
return cnt[p];
}

一道经典题目:最大异或数

在给定的 N 个整数 A1,A2……AN 中选出两个进行 xor(异或)运算,得到的结果最大是多少?

输入格式

第一行输入一个整数 N。

第二行输入 N 个整数 A1~AN。

输出格式

输出一个整数表示答案。

数据范围

1≤N≤105,
0≤Ai<231

分析:很明显,需要把每一个整数拆成32位,然后逐步插入Trie树(这里就只有0和1两种了),所有处理完之后,我们对每一个数去找可能最大的异或数,然后取所有的最大值就好了。

具体如果找异或数呢,其实也就是遍历数的过程,如果有跟当前位相反的,就直接取,否则就只能取0。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include<iostream>
#include<vector>
using namespace std;
const int N=32*1e5+10;
int son[N][2],idx;
void insert(int x)
{
int p=0;
for(int i=31;i>=0;i--)
{
int bit=(x>>i)&1;
if(!son[p][bit])son[p][bit]=++idx;
p=son[p][bit];
}
}
int main()
{
int n;scanf("%d",&n);
vector<int>nums;
for(int i=0;i<n;i++){
int x;scanf("%d",&x);
insert(x);nums.push_back(x);
}
int ans=0;
for(int x:nums)
{
int sum=0;int p=0;
for(int i=31;i>=0;i--)
{
int bit=(x>>i)&1;
int op=bit^1;
if(son[p][op])
{
sum|=(1<<i);
p=son[p][op];
}
else p=son[p][bit];
}
ans=max(ans,sum);
}
printf("%d",ans);
}
  • 标题: Trie树
  • 作者: Tomfng
  • 创建于 : 2025-07-14 22:22:00
  • 更新于 : 2025-07-17 11:44:07
  • 链接: https://redefine.ohevan.com/2025/07/14/算法/Trie树/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
Trie树