字典树是一种支持快速插入、查询字符串以及查找字符串插入次数的多叉树结构,其根节点编号为 $0$,其他节点标识路径,边表示字符。

需要以下组件:
const int N = 1e6;
int trie[N][26], pass[N], end[N], idx = 1;
void insert(string s) {
int k = 1; // 根节点开始
pass[k]++; // 根节点肯定被经过
for (int i = 0; i < s.length(); i++) {
int j = s[i] - 'a'; // 建立字母映射
if (!trie[k][j]) trie[k][j] = ++idx; // 若结点不存在,则创建一个新的
k = trie[k][j]; // 往下走
pass[k]++;
}
end[k]++; // 结尾给单词计数器加 1
}
查询某个字符串是否存在及出现次数
从根节点开始查,若字母存在则沿这条字母的边走下来,走到结尾则返回插入次数;若字母不存在则返回 $0$.
int query(string s) {
int k = 1;
for (int i = 0; i < s.length(); i++) {
int j = s[i] - 'a';
if (!trie[k][j]) return 0; // 没路走,说明没加过这个单词,直接返回 0
k = trie[k][j]; // 往下走
}
return end[k];
}
查询以某字符串为前缀的字符串的个数
int queryPrefix(string s) {
int k = 1;
for (int i = 0; i < s.length(); i++) {
int j = s[i] - 'a';
if (!trie[k][j]) return 0; // 没路走,说明不是任何一个已添加字符串的前缀,直接返回 0
k = trie[k][j]; // 往下走
}
return pass[k];
}