AC自动机

简单版

luogu3808

ps.第一次写,不太美观,加强版的好看些

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath> 
#include <queue>
#define N 1000005
using namespace std; 

int n,ans;
int t,c[N][26],flag[N],f[N];
char ch[N];

void insert()
{
    int num,rt=0;
    for(int i=0;ch[i];i++)
    {
        num=ch[i]-'a';
        if(!c[rt][num]) c[rt][num]=++t;
        rt=c[rt][num];
    }
    flag[rt]++;
}

queue<int> q;
void getfail()
{
    for(int i=0;i<26;i++)
        if(c[0][i]) q.push(c[0][i]);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(int i=0;i<26;i++)
        {
            if(c[u][i]) f[c[u][i]]=c[f[u]][i],q.push(c[u][i]);
            else c[u][i]=c[f[u]][i];
        }
    }
}

int query()
{
    int rt=0;
    for(int i=0;ch[i];i++)
    {
        rt=c[rt][ch[i]-'a'];
        for(int j=rt;j&&flag[j]!=-1;j=f[j])
        {
            ans+=flag[j];
            flag[j]=-1;
        }
    }
    return ans;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",ch);
        insert();
    }
    getfail();
    scanf("%s",ch);
    query();
    printf("%d",ans);
    return 0;
}

加强版

luogu3796

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define N 1000005
using namespace std;

int n,t,Max,ans[160];
char ch[160][160],s[N];

struct node
{
    int c[N][26],flag[N],f[N];
    void clear()
    {
        memset(c[0],0,sizeof(c[0]));
        memset(f,0,sizeof(f));
        memset(flag,0,sizeof(flag));
    }
    void insert(char* x,int id)
    {
        int num,rt=0;
        for(int i=0;x[i];i++)
        {
            num=x[i]-'a';
            if(!c[rt][num]) c[rt][num]=++t;
            rt=c[rt][num];
        }
        flag[rt]=id;
    }
    void getfail()
    {
        queue<int> q;
        for(int i=0;i<26;i++)
            if(c[0][i]) q.push(c[0][i]);
        while(!q.empty())
        {
            int rt=q.front();q.pop();
            for(int i=0;i<26;i++)
            {
                if(c[rt][i]) f[c[rt][i]]=c[f[rt]][i],q.push(c[rt][i]);
                else c[rt][i]=c[f[rt]][i];
            }
        }
    }
    void query(char* x)
    {
        int rt=0;
        for(int i=0;x[i];i++)
        {
            rt=c[rt][x[i]-'a'];
            for(int t=rt;t;t=f[t])
            {
                if(flag[t]) 
                {
                    ans[flag[t]]++;
                    Max=max(Max,ans[flag[t]]);
                }
            }
        }
    }
}AC;

int main()
{
    while(1)
    {
        scanf("%d",&n);Max=0; 
        if(!n) break;
        for(int i=1;i<=n;i++) scanf("%s",ch[i]),AC.insert(ch[i],i);
        AC.getfail();
        scanf("%s",s);AC.query(s);
        printf("%d
",Max);
        for(int i=1;i<=n;i++)
            if(ans[i]==Max) printf("%s
",ch[i]);
        AC.clear();
        memset(ans,0,sizeof(ans));Max=0;
    }    
    return 0;
}
原文地址:https://www.cnblogs.com/XYZinc/p/7463257.html