2024.3.21 字典树
字典树
字典树的是一个外向树, 边权为一个字母, 一个节点连向儿子边的权值互不相同, 点权为根到当前节点的权值经过的字符串拼起来。
如果要查找某一个元素的位置, 从根节点开始. 找到相应位置, 如果没有当前这个点, 新建这个点。
由于字典树的性质 : 当前节点的权值是所以的儿子节点的权值的前缀, 所以可以快速求出数量
luoguP8306
模板题, 按上述方法模拟
#include<bits/stdc++.h>
using namespace std;
const int N = 3e6 + 5;
string s;
int n, q, T;
struct TRIE{
int tot = 1, u;
struct Node{
int son[62];
int cnt;
void clear(){
for(int i = 0; i < 62; ++i){
son[i] = 0;
}
cnt = 0;
}
}trie[N];
int con(char c){
return (c <= 'z' && c >= 'a' ? c - 'a' + 26 : c <= 'Z' && c >= 'A' ? c - 'A' : c - '0' + 52);
}
void Insert(string s){
u = 1;
for(auto c : s){
if(!trie[u].son[con(c)]){
trie[u].son[con(c)] = ++tot;
trie[tot].clear();
}
trie[u].cnt++;
u = trie[u].son[con(c)];
}
trie[u].cnt++;
}
int query(string s){
u = 1;
for(char c : s){
if(!trie[u].son[con(c)]){
return 0;
}
u = trie[u].son[con(c)];
}
return trie[u].cnt;
}
}a;
void S(){
a.tot = 1;
a.trie[1].clear();
cin >> n >> q;
for(int i = 1; i <= n; ++i){
cin >> s;
a.Insert(s);
}
for(int i = 1; i <= q; ++i){
cin >> s;
cout << a.query(s) << '\n';
}
}
int main(){
ios::sync_with_stdio(0), cin.tie(0);
for(cin >> T; T--; S()){
}
return 0;
}