长期留坑
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 }