OI loves Algorithm(二)——字典树 Trie

更新第二期啦!


Trie 是什么,怎么写

image
是不是感觉挺熟悉?
没错,以前的一道G题放过这个图片。

可以发现,这棵字典树用边来代表字母,而从根结点到树上某一结点的路径就代表了一个字符串。举个例子, $ 1 \to 4 \to 8 \to 12 $ 表示的就是字符串 caa

trie 的结构非常好懂,我们用 $ \delta(u, c) $ 表示结点 $ u $ 的 $ c $ 字符指向的下一个结点,或着说是结点 $ u $ 代表的字符串后面添加一个字符 $ c $ 形成的字符串的结点。( $ c $ 的取值范围和字符集大小有关,不一定是 $ 0 \sim 26 $。)

有时需要标记插入进 trie 的是哪些字符串,每次插入完成时在这个字符串所代表的节点处打上标记即可。——OI Wiki

那字典树怎么写呢?
很简单,只需要实现一棵 26 叉树即可。
不写了,已经被打死了还写什么写


这样,节点诞生!

class trie_node {
	public:
		trie_node() {
			memset(child, -1, sizeof child);
		}
		int child[128];
} trie[100005];

int node_cnt = 0;

那如何插入一个字符串来更新 Trie 树呢?
从根节点开始,不断来到一个孩子(child[s[i]])。
如果没有孩子,则插入一个孩子——

int create() {
	return node_cnt++;
}

void construct(string s) {
	int node = 0;
	for (char ch : s) {
		if (trie[node].child[ch] != -1) {
			node = trie[node].child[ch];
		} else {
			node = (trie[node].child[ch] = create());
		}
	}
}

蛮简单的吧?

板子题

Luogu P2580 于是他错误的点名开始了
Luogu P5755 [NOI2000] 单词查找树
注意了!
P5755 的范围是 $ 1 \leq \sum|S| \leq 100000 $ ,
其中 S 表示字符串。(反正 $ 100000 $ 是可以的)
开大了会 MLE (┭┮﹏┭┮)。今天我就由于开了 $ 500000 $ 爆零了……

进阶题

ABC268G Random Student ID
题解:ABC268G

posted @ 2022-10-04 10:28  A-Problem-Solver  阅读(23)  评论(0编辑  收藏  举报