HDU 3065 病毒侵袭持续中(AC自动机模板)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
#define prt(k) cout<<#k"="<<k<<endl;
#define ll long long
const int N=2e5+8;
const int M=2e6+7;
char buf[M];

int next[N][128],fail[N],end[N];
int L,root;
int newnode()
{
    for(int i=0;i<128;i++)
        next[L][i]=-1;
    end[L++]=0;
    return L-1;
}
void init()
{
    L=0;
    root=newnode();
}
void insert(char buf[],int v)
{
    int len=strlen(buf),u=root;
    for(int i=0;i<len;i++)
    {
        if(next[u][buf[i]]==-1)
            next[u][buf[i]]=newnode();
        u=next[u][buf[i]];
    }
    end[u]=v;
}
void build()
{
    queue<int> q;
    for(int i=0;i<128;i++)
    {
        int& tmp=next[root][i];
        if(tmp==-1)
            tmp=root;
        else
        {
            fail[tmp]=root;
            q.push(tmp);
        }
    }
    while(!q.empty())
    {
        int u=q.front(); q.pop();
        for(int i=0;i<128;i++)
        {
            int& tmp=next[u][i];
            if(tmp==-1)
                tmp=next[fail[u]][i];
            else
            {
                fail[tmp]=next[fail[u]][i];
                q.push(tmp);
            }
        }
    }
}
int ans[2211];
int query(char buf[])
{
    int len=strlen(buf),u=0;
    memset(ans,0,sizeof ans);
    for(int i=0;i<len;i++)
    {
        u=next[u][buf[i]];
        for(int v=u;v!=root;v=fail[v])
            if(end[v])
            ans[end[v]]++;
    }
}
char dic[1221][88];
int main()
{
    int n;
    while(scanf("%d",&n)==1)
    {
        init();
        for(int i=1;i<=n;i++)
        {
            scanf("%s",dic[i]);
            insert(dic[i],i);
        }
        build();
        scanf("%s",buf);
        query(buf);
        for(int i=1;i<=n;i++)
            if(ans[i])
            printf("%s: %d\n",dic[i],ans[i]);
    }
}

你可能感兴趣的:(HDU 3065 病毒侵袭持续中(AC自动机模板))