AC自动机

#include <bits/stdc++.h>
using namespace std;
constexpr int maxn=2e5+10;
int n;
int ans[maxn],tot,id[maxn],pid;
struct _ {int ch[26],fail,cnt,id,d;}tr[maxn];
void trie(char s[],int &id)
{
    int x=0;
    for (int i=1;s[i];i++)
    {
        int &son=tr[x].ch[s[i]-'a'];
        if (!son) son=++tot;
        x=son;
    }
    if (!tr[x].id) tr[x].id=++pid;
    id=tr[x].id;
}
void Build()
{
    queue<int> q;
    for (int i=0;i<26;i++)
        if (tr[0].ch[i]) q.push(tr[0].ch[i]);
    while (!q.empty())
    {
        int x=q.front();q.pop();
        for (int i=0;i<26;i++)
        {
            if (tr[x].ch[i])
            {
                tr[tr[x].ch[i]].fail=tr[tr[x].fail].ch[i];
                tr[tr[tr[x].fail].ch[i]].d++;
                q.push(tr[x].ch[i]);
            }
            else tr[x].ch[i]=tr[tr[x].fail].ch[i];
        }
    }
}
void que(char s[])
{
    int x=0;
    for (int i=1;s[i];i++)
    {
        x=tr[x].ch[s[i]-'a'];
        tr[x].cnt++;
    }
}
void topo()
{
    queue<int> q;
    for (int i=0;i<=tot;i++)
        if (!tr[i].d)
            q.push(i);
    while (!q.empty())
    {
        int x=q.front();q.pop();
        ans[tr[x].id]=tr[x].cnt;
        int y=tr[x].fail;
        tr[y].cnt+=tr[x].cnt;
        if (!--tr[y].d)
            q.push(y);
    }
}
char s[maxn*10];
int idx[maxn];
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        trie(s,idx[i]);
    }
    Build();
    scanf("%s",s+1);
    que(s),topo();
    for (int i=1;i<=n;i++) printf("%d\n",ans[idx[i]]);
    return 0;
}
posted @ 2026-07-29 11:42  msjing  阅读(8)  评论(0)    收藏  举报