hdu2222-AC自动机

Orz  Kuangbin和昀牛--

 


 

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>

using namespace std;

#define INF 1<<29
#define eps 1e-8
#define A system("pause")
#define rep(i,h,n) for(int i=(h);i<(n);i++)
#define ms(a,b) memset((a),(b),sizeof(a))

const int maxn=500000+10;

struct AC_machine
{
       int next[maxn][26],fail[maxn],end[maxn];
       int root,L;
       inline int newnode()
       {
            rep(i,0,26)
                 next[L][i]=-1;
            end[L++]=0;
            return L-1;
       }
       inline void init()
       {
            L=0;
            root=newnode();
       }
       inline void  insert(char str[])
       {
            int len=strlen(str);
            int now=root;
            rep(i,0,len)
            {
                 if(next[now][str[i]-'a']==-1)//当前结点不存在,新建结点;
                     next[now][str[i]-'a']=newnode();
                 now=next[now][str[i]-'a'];//指向该结点;
            }
            end[now]++;
       }
       inline void build_AC()//BFS构建AC自动机的过程;
       {
             queue<int>q;
             fail[root]=root;//根节点的失败指针指向自己;
             rep(i,0,26)
             {
                  if(next[root][i]==-1)
                      next[root][i]=root;
                  else
                  {
                      fail[next[root][i]]=root;
                      q.push(next[root][i]);
                  }
             }
             while(!q.empty())
             {
                  int now=q.front();
                  q.pop();
                  rep(i,0,26)
                  {
                       if(next[now][i]==-1)
                            next[now][i]=next[fail[now]][i];
                       else
                       {
                            fail[next[now][i]]=next[fail[now]][i];
                            q.push(next[now][i]);
                       }
                  }
             }
       }
       inline int match(char str[])
       {
              int len=strlen(str);
              int now=root;
              int res=0;
              rep(i,0,len)
              {
                   now=next[now][str[i]-'a'];
                   int temp=now;
                   while(temp!=root)
                   {
                        res+=end[temp];
                        end[temp]=0;
                        temp=fail[temp];
                   }
              }
              return res;
       }
       inline void debug()
       {
            for(int i = 0;i < L;i++)
            {
                printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
                for(int j = 0;j < 26;j++)
                    printf("%2d",next[i][j]);
                    printf("]\n");
            }
       }
}AC;

char str[maxn<<1];
int test,n;
int main()
{
    scanf("%d",&test);
    while(test--)
    {
         scanf("%d",&n);
         AC.init();
         rep(i,0,n)
         {
              scanf("%s",str);
              AC.insert(str);
         }
         //AC.debug();
         AC.build_AC();
         scanf("%s",str);
         printf("%d\n",AC.match(str));
    }
    //A;
    return 0;
}

* This source code was highlighted by YcdoiT. ( style: Emacs )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值