AC自动机模板复习:1.建立模式串组成的Trie树 2.连fail边
摘自 ouuan的博客
代码
#include<bits/stdc++.h>
using namespace std;
const int maxl=2e5+5;
const int maxn=2e6+5;
int n,tot;
char c[maxl],s[maxn];
int match[maxl];
struct tree
{
int son[26],fail,end;
}tr[maxl];
void insert(char *ss,int cnt)
{
int len=strlen(ss),now=0;
for(int j=0;j<len;j++)
{
int dig=ss[j]-'a';
if(!tr[now].son[dig]) tr[now].son[dig]=++tot;
now=tr[now].son[dig];
}
tr[now].end++; match[cnt]=now;
}
void build()
{
queue <int> q;
for(int i=0;i<26;i++) if(tr[0].son[i]) q.push(tr[0].son[i]);
while(!q.empty())
{
int u=q.front(); q.pop();
for(int i=0;i<26;i++)
{
if(tr[u].son[i])
{
tr[tr[u].son[i]].fail=tr[tr[u].fail].son[i];
q.push(tr[u].son[i]);
}
else tr[u].son[i]=tr[tr[u].fail].son[i];
}
}
}
int siz[maxl];
int head[maxl],cntt;
struct edge
{
int to,nxt;
}e[maxl];
void add(int x,int y)
{
e[++cntt].to=y;
e[cntt].nxt=head[x];
head[x]=cntt;
}
void dfs(int u)
{
for(int i=head[u];i;i=e[i].nxt)
{
int to=e[i].to;
dfs(to);
siz[u]+=siz[to];
}
}
void solve()
{
int len=strlen(s),now=0;
for(int i=0;i<len;i++)
{
now=tr[now].son[s[i]-'a'];
siz[now]++;
}
for(int i=1;i<=tot;i++)
add(tr[i].fail,i);
dfs(0);
for(int i=1;i<=n;i++)
printf("%d\n",siz[match[i]]);
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",c);
insert(c,i);
}
scanf("%s",s);
build();
solve();
return 0;
}