【AC自动机模板】【HDU2222】 Keywords Search

来源:互联网 发布:农村选举知乎 编辑:程序博客网 时间:2024/06/06 03:47

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222

如果按照N <= 10000,L <= 50 ,开500000的节点好像会MLE
但其实250000就够了
最好还是指针动态申请空间(可是我不会那样写QAQ)……待更

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#define ULL unsigned long longusing namespace std;int t,n,nxt[260010][26];int c[260010],fail[260010],num;char ss[1100000];void insert(char *s){    int t=1,len=strlen(s+1);    for(int i=1;i<=len;i++)    {        if(nxt[t][s[i]-'a']==0) nxt[t][s[i]-'a']=++num;        t=nxt[t][s[i]-'a'];    }    c[t]++;}void makeAC(){    queue<int> q;    q.push(1);    int point,t;    while(!q.empty())    {        point=q.front();        q.pop();        for(int i=0;i<26;i++)   if(nxt[point][i])        {            t=fail[point];            while(t)            {                if(nxt[t][i]) {fail[nxt[point][i]]=nxt[t][i];break;}                t=fail[t];            }               if(t==0) fail[nxt[point][i]]=1;            q.push(nxt[point][i]);        }    }}int count(char *s){    int t=1,cnt=0,tt;    int len=strlen(s+1);    for(int i=1;i<=len;i++)    {        if(nxt[t][s[i]-'a']) t=nxt[t][s[i]-'a'];        else        {            while(t!=1&&!nxt[t][s[i]-'a']) t=fail[t];            if(t!=1||nxt[t][s[i]-'a']) t=nxt[t][s[i]-'a'];        }        tt=t;        while(tt!=1&&c[tt]!=-1)        {            cnt+=c[tt];            c[tt]=-1;            tt=fail[tt];        }    }    return cnt;}int main(){    scanf("%d",&t);    char s[111];    while(t--)    {        num=1;        memset(nxt,0,sizeof(nxt));        memset(c,0,sizeof(c));        memset(fail,0,sizeof(fail));        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            scanf("%s",s+1);            insert(s);        }        makeAC();        scanf("%s",ss+1);        printf("%d\n",count(ss));    }    return 0;}
原创粉丝点击