HDU2222【AC自动机(基础·模板)】

来源:互联网 发布:河北邢台招聘程序员 编辑:程序博客网 时间:2024/06/05 11:25

戳》》》【点窝】

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Frist AC zi dong ji(Aho-Corasick Automation) of life

#include <bits/stdc++.h>using namespace std;const int N=5e5+10;    //10000个串,长度为50 struct Trie{    int num;    Trie *next[27],*fail;};Trie q[N],*root;int tol;Trie* Creat(){    Trie *p;    p=&q[tol++];    p->fail=NULL;    p->num=0;    for(int i=0;i<26;i++)        p->next[i]=NULL;    return p;}void Insert(char *str){    Trie *p=root;    int index,len=strlen(str);    for(int i=0;i<len;i++)    {        index=str[i]-'a';        if(p->next[index]==NULL)            p->next[index]=Creat();        p=p->next[index];    }    p->num++;}void Build_Ac(){    queue<Trie*>que;    que.push(root);    while(!que.empty())    {        Trie *p=que.front();que.pop();        for(int i=0;i<26;i++)        {            if(p->next[i]!=NULL)            {                if(p==root)                    p->next[i]->fail=root;                else                {                    Trie *temp;                    temp=p->fail;                    while(temp!=NULL)                    {                        if(temp->next[i]!=NULL)                        {                            p->next[i]->fail=temp->next[i];                            break;                        }                        temp=temp->fail;                    }                    if(temp==NULL)                        p->next[i]->fail=root;                }                que.push(p->next[i]);            }        }    }}char word[1000010];int Query(){    int ans,index,len;    Trie *p=root;    ans=0;    len=strlen(word);    for(int i=0;i<len;i++)    {        index=word[i]-'a';        while(p->next[index]==NULL && p!=root)//失配跳转到失败指针             p=p->fail;        p=p->next[index];        if(p==NULL)    //还是失配             p=root;        Trie *temp=p;    //p不动,temp计算后缀串         while(temp!=root && temp->num!=-1)        {            ans+=temp->num;            temp->num=-1;            temp=temp->fail;        }    }    return ans;}int main(){    char s[51];    int T;    scanf("%d",&T);    while(T--)    {        int n;        tol=0;        root=Creat();        scanf("%d",&n);        while(n--)        {            scanf("%s",s);            Insert(s);            }        Build_Ac();        scanf("%s",word);        printf("%d\n",Query());    }    return 0;}


0 0
原创粉丝点击