一些重要提醒

长期留坑

1.AC自动机多模式串匹配问题

对于要统计各个模式串在文本中的出现次数,对于每个当前节点不能直接暴力跳$fail$

复杂可以退化到$O(n^2)$

$aaaaaa……aaa$可以卡掉

要将$fail$指针反向建出来,明显这是棵树,然后统计其子树大小

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=2*1e5+100;
 4 int n,tot,wh[N],cnt[N];
 5 struct node
 6 {
 7     int son[26],fail;
 8 }sh[N];
 9 string s,t;
10 vector <int> e[N];
11 void build(int x)
12 {
13     int p=1;
14     for (int i=0;i<(int)t.size();i++)
15     {
16         if (!sh[p].son[t[i]-'a'])
17         {
18             tot++;
19             sh[p].son[t[i]-'a']=tot;
20         }
21         p=sh[p].son[t[i]-'a'];
22     }
23     wh[x]=p;
24 }
25 void build_fail()
26 {
27     queue <int> q;
28     q.push(1);
29     while (!q.empty())
30     {
31         int x=q.front();
32         q.pop();
33         for (int i=0;i<26;i++)
34         {
35             if (!sh[x].son[i])
36             {
37                 if (x==1)
38                   sh[x].son[i]=1;
39                 else
40                   sh[x].son[i]=sh[sh[x].fail].son[i];
41             }
42             else
43             {
44                 if (x==1)
45                   sh[sh[x].son[i]].fail=1;
46                 else
47                   sh[sh[x].son[i]].fail=sh[sh[x].fail].son[i];
48                 q.push(sh[x].son[i]);
49             }
50         }
51     }
52 }
53 void match()
54 {
55     int p=1;
56     for (int i=0;i<(int)s.size();i++)
57     {
58         p=sh[p].son[s[i]-'a'];
59         cnt[p]++;
60     }
61 }
62 void dfs(int x,int fa)
63 {
64     for (int i=0;i<(int)e[x].size();i++)
65     {
66         int u=e[x][i];
67         if (u!=fa)
68         {
69             dfs(u,x);
70             cnt[x]+=cnt[u];
71         }
72     }
73 }
74 int main()
75 {
76     tot=1;
77     scanf("%d",&n);
78     for (int i=1;i<=n;i++)
79     {
80         cin>>t;
81         build(i);
82     }
83     build_fail();
84     cin>>s;
85     match();
86     for (int i=2;i<=tot;i++)
87     {
88         e[i].push_back(sh[i].fail);
89         e[sh[i].fail].push_back(i);
90     }
91     dfs(1,1);
92     for (int i=1;i<=n;i++)
93       printf("%d\n",cnt[wh[i]]);
94 }
View Code

猜你喜欢

转载自www.cnblogs.com/huangchenyan/p/11900882.html
今日推荐