hdu-5687(字典树)
题意:中文题;
解题思路:增加和查询就不说了,标准操作,就是删除操作:删除操作的时候,我们把给定字符串先在字典树中遍历一遍,然后算出这个字符串最后一个字符的出现次数,然后在遍历一遍,每个节点都减去这个次数,最后节点的儿子全部归零;
最开始我是只考虑的最后节点,中间节点都没考虑,这样会出现一个问题就是:插入abdefg,删除abcd的时候,查询abc还是会有答案,所有中间过程也得减去;
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1200500 using namespace std; int trie[maxn][26]; int num[maxn]={-1}; int root; int tot; int t,n; void init() { memset(trie,0,sizeof(trie)); memset(num,0,sizeof(num)); tot=0; } void get_trie(char *s) { root=0; int slen=strlen(s); for(int i=0;i<slen;i++) { int id=s[i]-'a'; if(!trie[root][id]) { trie[root][id]=++tot; } root=trie[root][id]; num[root]++; } } int query(char *s) { root=0; int slen=strlen(s); for(int i=0;i<slen;i++) { int id=s[i]-'a'; if(!trie[root][id]) { return 0; } root=trie[root][id]; } return num[root]; } void delete_trie(char *s) { root=0; int cnt=0; int slen=strlen(s); for(int i=0;i<slen;i++) { int id=s[i]-'a'; if(!trie[root][id]) { return; } root=trie[root][id]; } cnt=num[root]; root=0; for(int i=0;i<slen;i++) { int id=s[i]-'a'; root=trie[root][id]; num[root]=num[root]-cnt; } for(int i=0;i<=25;i++) trie[root][i]=0; } int main() { char s[10],a[50]; scanf("%d",&t); init(); while(t--) { scanf("%s",s); scanf("%s",a); if(s[0]=='i') { get_trie(a); } else if(s[0]=='s') { int flag=query(a); if(flag==0) printf("No\n"); else printf("Yes\n"); } else { delete_trie(a); } } }