例题:bzoj1819
https://www.lydsy.com/JudgeOnline/problem.php?id=1819
注意:trie一定要开够数组,不然会RE。
注意:trie一定要开够数组,不然会RE。
注意:trie一定要开够数组,不然会RE。
知识点:1.较好的Trie入门题,理解了Trie
2.本题的Trie不同于模板Trie,其因查询时的需要,在查询过程中增加了一个bool参数来记录是否已进行修改。并在迭代的时候,调整了不同的参数来实现了题目所讲述的删除,修改,增加。
3.可以通过调整参数来实现一些非常规操作。
4.Trie的实现:一个节点可以开26个儿子(提前开好)(26这个值随题目而变,不是定值)来实现Trie.
5.边上记录的才是字符。
#include<bits/stdc++.h> using namespace std; const int MAXN=10000+7; int Trie[MAXN*20][26],visx[MAXN]; char s[22]; bool p[MAXN*20],vis[MAXN*20],word; int n,m,u,len,tot,vistot; void Insert() { int root = 0,len = strlen(s); for(int i = 0;i < len;i++) { char c = s[i] - 'a'; if(!Trie[root][c])Trie[root][c] = ++tot; root = Trie[root][c]; } p[root] = 1; } void DFS(int rt,int l,bool f) { if(l==len&&p[rt]&&!f) { word=1;return; } if(l==len&&p[rt]&&f) { if(!vis[rt]) vis[visx[++vistot]=rt]=1; return; } int c=s[l]-'a'; if(!f) { if(l<len) DFS(rt,l+1,1); for(register int i=0;i<26;++i) if(Trie[rt][i]) { DFS(Trie[rt][i],l,1); if(i!=c) DFS(Trie[rt][i],l+1,1); } } if(l>=len) return; if(Trie[rt][c]) DFS(Trie[rt][c],l+1,f); } int main() { scanf("%d%d",&n,&m); for(register int i=1;i<=n;++i) scanf("%s",s),Insert(); for(register int i=1;i<=m;++i) { scanf("%s",s);len=strlen(s); DFS(0,0,0); if(word) printf("-1 "); else printf("%d ",vistot); while(vistot) vis[visx[vistot--]]=0; word=0; } return 0; }