AC自动机

AC自动机

#include<iostream>
#include<cstdio>
#include<memory.h>
#include<queue>
#include<cstring>
using namespace std;
#define ri register int
#define rep(i,a,b) for(ri i=(a);i<=(b);i++)
#define N 1000100
#define A 26
int n;
char S[151][71];
char T[N];
struct AC{
    int cnt;
    int ch[N][A],fail[N],val[N],ans[N];
    inline void clear(){
        cnt=0;
        memset(ch,0,sizeof(ch));
        memset(fail,0,sizeof(fail));
        memset(val,0,sizeof(val));
        memset(ans,0,sizeof(ans));
    }
    inline void insert(char* s,int x){
        ri u=0,l=strlen(s);
        rep(i,0,l-1){
            ri v=s[i]-'a';
            if(!ch[u][v])
                ch[u][v]=++cnt;
            u=ch[u][v];
        }
        val[u]=x;
    }
    inline void getFail(){
        queue<int> q;
        rep(i,0,A-1)
            if(ch[0][i]){
                fail[ch[0][i]]=0;
                q.push(ch[0][i]);
            }
        for(;!q.empty();){
            int u=q.front();
            q.pop();
            rep(i,0,A-1){
                if(ch[u][i]){
                    fail[ch[u][i]]=ch[fail[u]][i];
                    q.push(ch[u][i]);
                }
                else ch[u][i]=ch[fail[u]][i];
            }
        }
    }
    inline void query(char* s){
        ri u=0,l=strlen(s),res=0;
        rep(i,0,l-1){
            u=ch[u][s[i]-'a'];
            for(ri t=u;t;t=fail[t])
                ans[val[t]]++;
        }
        rep(i,1,n)
            res=max(res,ans[i]);
        printf("%d\n",res);
        rep(i,1,n)
            if(ans[i]==res)
                printf("%s\n",S[i]);
    }
} ac;
int main(){
    for(;scanf("%d",&n)==1 && n;){
        ac.clear();
        rep(i,1,n){
            scanf("%s",S[i]);
            ac.insert(S[i],i);
        }
        ac.getFail();
        scanf("%s",T);
        ac.query(T);
    }
    return 0;
}
posted @ 2019-01-19 09:24 Pelom 阅读(...) 评论(...) 编辑 收藏