0%

Trie树(字典树)

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <cstdio>
using namespace std;

const int N = 1e5 + 10;
int sons[N][26], idx, times[N];

void insert(char str[])
{
int p = 0, c;
for(int i = 0; str[i]; ++i)
{
c = str[i] - 'a';
if(!sons[p][c]) sons[p][c] = ++idx;
p = sons[p][c];
}
++times[p];
}

int query(char str[])
{
int p = 0, c;
for(int i = 0; str[i]; ++i)
{
c = str[i] - 'a';
if(!sons[p][c]) return 0;
p = sons[p][c];
}
return times[p];
}

int main()
{
int n;
scanf("%d", &n);
while(n--)
{
char order[2], strs[N];
scanf("%s%s", &order, &strs);
if(order[0] == 'I')
insert(strs);
else if(order[0] == 'Q')
printf("%d\n", query(strs));
}
return 0;
}

Trie树的经典应用:最大异或对(LeetCode421.数组中两个数的最大异或值)

注意INT型为1符号位加31位数值位。

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
//插入操作
void insert(int val)
{
int p = 0, v;
for(int i = 30; i >= 0; --i)
{
v = (val >> i) & 1;
if(!sons[p][v]) sons[p][v] = ++idx;
p = sons[p][v];
}
}

//求异或的查询操作
int query(int val)
{
int p = 0, v, res = 0;
for(int i = 30; i >= 0; --i)
{
v = (val >> i) & 1;
if(sons[p][!v])
res += 1 << i, p = sons[p][!v];//注意这里判断!v是否存在
else
p = sons[p][v];
}
return res;
}