今天学一发Trie树,为了接下来的AC自动机做准备。
Trie树好像还是挺重要的,经常有题目的优化需要用到Trie树,比如说一些异或的题目。
其实Trie树还是挺好理解的,就是把一个字符串放到一棵树上,每一条树边都表示一个字母,每一个叶节到根节点的路径都表示一个字符串。
对于查询前缀,Trie树也能轻松应付,每次插入一个字符串时,就在每一个节点的计数变量上更新一下即可。
于是这题就被轻松水过啦。
附上AC代码:
#include <cstdio>
#include <cstring>
using namespace std;
struct trie{
int c[1000010],nt[1000010][26],sz;
inline void clear(){
memset(c,0,sizeof c),memset(nt,0,sizeof nt);
}
inline void insert(char *a){
int now=0;
for (int i=1; i<=strlen(a+1); ++i){
if (!nt[now][a[i]-'a']) nt[now][a[i]-'a']=++sz;
now=nt[now][a[i]-'a'],++c[now];
}
return;
}
inline int query(char *a){
int now=0;
for (int i=1; i<=strlen(a+1); ++i){
if (!nt[now][a[i]-'a']) return 0;
now=nt[now][a[i]-'a'];
}
return c[now];
}
}t;
int n;
char s[12];
int main(void){
scanf("%d",&n),t.clear();
while (n--) scanf("%s",s+1),t.insert(s);
scanf("%d",&n);
while (n--) scanf("%s",s+1),printf("%d\n",t.query(s));
return 0;
}