hdu 2222 史上最裸 AC自动机

来源:互联网 发布:海淘转运系统源码 编辑:程序博客网 时间:2024/06/05 18:05
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<queue>#include<set>using namespace std;const int maxn=52;const int maxm=1000002;char s[maxm],str[maxn];int t,n,m,ans,res;struct node{    int idx,flag;    node *fail;    node *next[27];    node()    {        memset(next,0,sizeof(next));        idx=0;        flag=0;        fail=NULL;    }};void Insert(node *rt,char s[]){    node *p=rt;    int i=0;    while(s[i])    {        int k=s[i++]-'a';        if(p->next[k]==NULL)p->next[k]=new node();        p=p->next[k];    }    p->flag=1;//字符串结尾    p->idx++;//代表第几个字符串}void build_AC(node *rt){    int i,j=0;    queue<node*>q;    rt->fail=NULL;    q.push(rt);    while(!q.empty())    {        node *p=q.front();        q.pop();        for(i=0;i<26;i++)        {            if(p->next[i]!=NULL)//寻找当前子树的失败指针            {                if(p==rt)                {                    p->next[i]->fail=rt;                }else                {                    node *tmp=p->fail;                    while(tmp!=NULL)                    {                        if(tmp->next[i]!=NULL)//找到失败指针                        {                            p->next[i]->fail=tmp->next[i];                            break;                        }                        tmp=tmp->fail;                    }                    if(tmp==NULL)p->next[i]->fail=rt;//无法获取,当前子树的失败指针为根                }                q.push(p->next[i]);            }        }    }}int query_AC(node *rt,char s[]){    int i=0,j;    ans=0;    node *p=rt;    while(s[i])    {        int k=s[i++]-'a';        while(p->next[k]==NULL&&p!=rt)p=p->fail;//失配        p=p->next[k];        if(p==NULL)p=rt;//失配指针为根        node *tmp=p;        while(tmp!=rt&&tmp->idx>0)        {             ans+=tmp->idx;             tmp->idx=-1;            tmp=tmp->fail;        }    }    return ans;}int main(){    cin>>t;    while(t--)    {        cin>>n;        int i,j;        node *rt=new node();        for(i=1; i<=n; i++)        {            scanf("%s",&str);            Insert(rt,str);        }        build_AC(rt);        scanf("%s",s);        int res=query_AC(rt,s);        cout<<res<<endl;    }    return 0;}


原创粉丝点击