Repository HDU - 2846 字典树

  题意:给出很多很多很多很多个 单词 类似搜索引擎一下 输入一个单词 判断有一个字符串包含这个单词

  思路:字典树变体,把每个单词的后缀都扔字典树里面,这里要注意dd是一个单词 但是把d 和dd都放字典树

  拿d匹配这一个单词会匹配两次 所以要开个数组记录一下上一个使该位置数量加一的字符串 如果该字符串不是同一个

  那就可以加加了

  TLE:还是数组大小的问题 字典树有毒!因为一个字符串可以拆成很多个后缀所以必须开大,开大了就过了。。。

  

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=500010;
 4 struct Trie{
 5     int ch[maxn][27];
 6     int num[maxn];
 7     int lastnum[maxn];
 8     int size=1;
 9     void init(){
10         memset(ch,0,sizeof(ch));
11         memset(num,0,sizeof(num));
12         memset(lastnum,0,sizeof(lastnum));
13         size=1;
14     }
15     void insert(char*s,int ok){
16         int i=0,rc=0;
17         for(;s[i]!='\0';i++){
18             int id=s[i]-'a';
19             //coutr<<rc<<endl;
20             if(ch[rc][id]==0){
21                 ch[rc][id]=size++;
22             }
23             rc=ch[rc][id];
24               if(lastnum[rc]==0||lastnum[rc]!=ok)num[rc]++,lastnum[rc]=ok;
25             //cout<<" "<<num[rc]<<" "<<rc<<endl;
26         }
27     }
28     int  find(char*s){
29         int i=0,rc=0;
30         for(;s[i]!='\0';i++){
31             int id=s[i]-'a';
32             if(ch[rc][id]==0)return 0;
33             rc=ch[rc][id];
34         }
35         return num[rc];
36     }
37 }trie;
38 char s[100];
39 char s1[100];
40 int main(){
41     int n;
42     trie.init();
43     scanf("%d",&n);
44     for(int i=0;i<n;i++){
45         scanf("%s",s);
46         int len=strlen(s);
47         for(int j=0;j<len;j++){
48             trie.insert(s+j,i+1);
49         }
50     }
51     int t;
52     scanf("%d",&t);
53     while(t--){
54         scanf("%s",s);
55         printf("%d\n",trie.find(s));
56     }
57     return 0;
58 }

猜你喜欢

转载自www.cnblogs.com/ttttttttrx/p/10252638.html