Trie图 模板

trie图实际上是优化的一种AC自动机。

trie图是在trie树上加一些失配指针,实际上是类似KMP的一种字符串匹配算法。

失配指针类似KMP的nx数组,有效地利用了之前失配的信息,优化了时间复杂度。

比如trie树上的abc那个节点,失配后会指向bc。

所以我们需要知道上一层节点的fail指针,来求出这一层的fail指针。

那就~BFS吧~

懒得写了,大佬们讲的都比我好。

哪天有空了,可能会再详细写一写吧,补两张图什么的。

模板题:洛谷 P3808 【模板】AC自动机(简单版)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 using namespace std;
 6 
 7 int n,sz;
 8 int s[1000005][30];
 9 int ed[1000005];
10 int fal[1000005];
11 char str[1000005];
12 
13 void ins(char *a)
14 {
15     int l=strlen(a+1);
16     int p=0;
17     for(int i=1;i<=l;i++)
18     {
19         int c=a[i]-'a'+1;
20         if(!s[p][c])s[p][c]=++sz;
21         p=s[p][c];
22     }
23     ed[p]++;
24 }
25 
26 queue<int>qq;
27 
28 void build()
29 {
30     for(int i=1;i<=26;i++)
31         if(s[0][i])qq.push(s[0][i]);
32     while(!qq.empty())
33     {
34         int p=qq.front();
35         qq.pop();
36         for(int i=1;i<=26;i++)
37         {
38             if(s[p][i])fal[s[p][i]]=s[fal[p]][i],qq.push(s[p][i]);
39             else s[p][i]=s[fal[p]][i];
40         }
41     }
42 }
43 
44 int cal(char *a)
45 {
46     int l=strlen(a+1);
47     int p=0,ans=0;
48     for(int i=1;i<=l;i++)
49     {
50         int c=a[i]-'a'+1;
51         p=s[p][c];
52         for(int j=p;j&&~ed[j];j=fal[j])
53         {
54             ans+=ed[j];
55             ed[j]=-1;
56         }
57     }
58     return ans;
59 }
60 
61 int main()
62 {
63     scanf("%d",&n);
64     char str[1000005];
65     for(int i=1;i<=n;i++)
66     {
67         scanf("%s",str+1);
68         ins(str);
69     }
70     build();
71     scanf("%s",str+1);
72     int ans=cal(str);
73     printf("%d",ans);
74     return 0;
75 }
原文地址:https://www.cnblogs.com/cervusy/p/9680718.html