【AC自动机】hdu2222 Keywords Search

AC自动机模板题,给你n个模式串和一个文本串,问你有几个模式串在文本串出现过。

注意防止重复统计

这里推荐一波郭大爷的介绍,简单易懂。

http://www.bilibili.com/video/av6295004/

这个视频里的hdu2222代码好像有点问题,我现在这份代码已经更改。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
queue<int>q;
int child[500010][26],fail[500010],cnts[500010],size;
void Insert(char S[])
{
    int len=strlen(S);
    int now=0;
    for(int i=0;i<len;++i)
      {
        if(!child[now][S[i]-'a'])
          child[now][S[i]-'a']=size++;
        now=child[now][S[i]-'a'];
      }
    if(cnts[now]==-1)
      cnts[now]=0;
    ++cnts[now];
}
void build()
{
    fail[0]=-1;
    q.push(0);
    while(!q.empty())
      {
        int U=q.front(); q.pop();
        for(int i=0;i<26;++i)
          if(child[U][i])
            {
              int V=fail[U];
              while(V!=-1)
                {
                  if(child[V][i])
                    {
                      fail[child[U][i]]=child[V][i];
                      break;
                    }
                  V=fail[V];
                }
              if(V==-1)
                fail[child[U][i]]=0;
              if(cnts[fail[child[U][i]]]!=-1 && cnts[child[U][i]]==-1)
                cnts[child[U][i]]=0;
              q.push(child[U][i]);
            }
      }
}
int calc(int U)//˳×ÅfailÖ¸Õë»ØÈ¥£¬¿´Í³¼Æµ½Á˼¸¸ö´®
{
    int res=0;
    while(U)
      {
      	if(cnts[U]==-1)
      	  break;
        res+=cnts[U];
        cnts[U]=-1;//·ÀÖ¹Öظ´Í³¼Æ
        U=fail[U];
      }
    return res;
}
int match(char S[])
{
    int len=strlen(S);
    int res=0,now=0;
    for(int i=0;i<len;++i)
      {
        if(child[now][S[i]-'a'])
          now=child[now][S[i]-'a'];
        else
          {
            int U=fail[now];
            while(U!=-1 && child[U][S[i]-'a']==0)
              U=fail[U];
            if(U==-1)
              now=0;
            else
              now=child[U][S[i]-'a'];
          }
        if(cnts[now]!=-1)
          res+=calc(now);
      }
    return res;
}
void Init()
{
    memset(child,0,sizeof(child));
    memset(fail,0,sizeof(fail));
    memset(cnts,-1,sizeof(cnts));
    size=1;
}
int T,n;
char s[1000010];
int main()
{
    //freopen("hdu2222.in","r",stdin);
    scanf("%d",&T);
    for(;T;--T)
      {
        Init();
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
          {
            scanf("%s",s);
            Insert(s);
          }
        build();
        scanf("%s",s);
        printf("%d\n",match(s));
      }
    return 0;
}
posted @ 2017-03-01 22:54  AutSky_JadeK  阅读(159)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト