HDU 2222 : Keywords Search

学习了字典树之后,来学一下AC自动机,其实挺简单的,但是很强大
这是一道AC自动机模板题
AC自动机学习博客:ac自动机最详细的讲解,让你一次学会ac自动机。

我的代码:

#include<cstdio>
#include<cstring>
using namespace std;

const int maxn=500000+100;

int trie[maxn][26],sum[maxn],fail[maxn],tot;
int que[maxn];

inline void insert(char* ch){

    int len=strlen(ch);
    int root=0;
    for(int i=0;i<len;i++){

        int ind=ch[i]-'a';
        if(!trie[root][ind]) trie[root][ind]=++tot;
        root=trie[root][ind];
    }
    sum[root]++;
}

inline void build_fail(){

    int l=0;
    int r=1;
    que[l]=0; // que[l]=root=0
    while(l<r){

        int tmp=que[l++];
        for(int i=0;i<=25;i++){

            int node=trie[tmp][i];
            if(node){

                if(tmp==0){

                    fail[node]=0;
                }
                else{

                    int node_tmp=fail[tmp];
                    while(!trie[node_tmp][i] && node_tmp){

                        node_tmp=fail[node_tmp];
                    }
                    if(trie[node_tmp][i]) fail[node]=trie[node_tmp][i];
                    else fail[node]=0;
                }
                que[r++]=node;
            }
        }
    }
}

inline int search(char* ch){

    int len=strlen(ch);
    int root=0;
    int cnt=0;
    for(int i=0;i<len;i++){

        int ind=ch[i]-'a';
        while(!trie[root][ind] && root) root=fail[root];
        root=trie[root][ind];
        if(root){

            int node_tmp=root;
            while(node_tmp){

                if(sum[node_tmp]>=0){

                    cnt+=sum[node_tmp];
                    sum[node_tmp]=-1;
                }
                else break;
                node_tmp=fail[node_tmp];
            }
        }
    }
    return cnt;
}

inline void init(){

    tot=0;
    memset(trie,0,sizeof(trie));
    memset(sum,0,sizeof(sum));
    memset(fail,0,sizeof(fail));
}

char str[maxn*2];

int main(){

    int T,n;
    scanf("%d",&T);
    while(T--){

        init();
        scanf("%d",&n);
        getchar();
        char ch[100];
        for(int i=1;i<=n;i++){

            scanf("%s",ch);
            insert(ch);
        }
        build_fail();
        scanf("%s",str);
        printf("%d\n",search(str));
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37960603/article/details/81169791