luoguP3808[模板]AC自动机(简单版)

传送门

ac自动机模板题,裸的多串匹配
代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
void read(int &x) {
    char ch; bool ok;
    for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
    for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
const int maxn=1e6+10;queue<int>q;bool vis[maxn];
int ed[maxn],fail[maxn],n,rt=1,id=1,ch[maxn][26],ans;char s[maxn];
void insert(char *s,int d)
{
    int len=strlen(s+1);rt=1;
    for(rg int i=1;i<=len;i++)
    {
        int now=s[i]-'a';
        if(!ch[rt][now])ch[rt][now]=++id;
        rt=ch[rt][now];
    }
    ed[d]=rt;
}
void bfs()
{
    q.push(1);
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(rg int i=0;i<26;i++)
        {
            if(!ch[x][i]){ch[x][i]=fail[x]?ch[fail[x]][i]:1;continue;}
            int j=fail[x],z=ch[x][i];q.push(z);
            while(j&&!ch[j][i])j=fail[j];
            if(j)fail[z]=ch[j][i];
            else fail[z]=1;
        }
    }
}
void solve()
{
    int len=strlen(s+1),j=1;
    for(rg int i=1;i<=len;i++)
    {
        int now=s[i]-'a';
        while(j&&!ch[j][now])j=fail[j];
        if(!ch[j][now])continue;j=ch[j][now];int k=j;
        while(k&&!vis[k])vis[k]=1,k=fail[k];
    }
    for(rg int i=1;i<=n;i++)if(vis[ed[i]])ans++;
    printf("%d\n",ans);
}
int main()
{
    read(n);
    for(rg int i=1;i<=n;i++)scanf("%s",s+1),insert(s,i);
    bfs(),scanf("%s",s+1),solve();
}
posted @ 2019-02-25 17:02  蒟蒻--lichenxi  阅读(104)  评论(0编辑  收藏  举报