HDU 2222 Keywords Search (AC自动机)

题目地址:HDU 2222
AC自动机第一发!真好奇这些算法是怎么被发明的。。算法的魅力真是无穷。
这题是AC自动机模板题。自己实在写不出来,比着kuangbin的模板写的= =
代码如下:

#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
#include <string>
#include <time.h>
using namespace std;
#define LL long long
#define pi acos(-1.0)
#pragma comment(linker, "/STACK:1024000000")
const int mod=9901;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
const int MAXN=1000000+300;
char s[MAXN];
struct Tire
{
        int next[500010][30], fail[500010], flag[500010];
        int root, L;
        int newnode()
        {
                for(int i=0;i<26;i++){
                        next[L][i]=-1;
                }
                flag[L++]=0;
                return L-1;
        }
        void init()
        {
                L=0;
                root=newnode();
        }
        void Insert(char s[])
        {
                int len=strlen(s), x, i, now=root;
                for(i=0;i<len;i++){
                        x=s[i]-'a';
                        if(next[now][x]==-1){
                                next[now][x]=newnode();
                        }
                        now=next[now][x];
                }
                flag[now]++;
        }
        void Build()
        {
                queue<int>q;
                fail[root]=root;
                for(int i=0;i<26;i++){
                        int v=next[root][i];
                        if(v==-1){
                                v=root;
                        }
                        else{
                                fail[v]=root;
                                q.push(v);
                        }
                }
                while(!q.empty()){
                        int u=q.front();
                        q.pop();
                        for(int i=0;i<26;i++){
                                int v=next[u][i];
                                if(v==-1){
                                        next[u][i]=next[fail[u]][i];
                                }
                                else{
                                        fail[v]=next[fail[u]][i];
                                        q.push(v);
                                }
                        }
                }
        }
        int Query(char s[])
        {
                int len=strlen(s), ans=0;
                int now=root, x;
                for(int i=0;i<len;i++){
                        x=s[i]-'a';
                        now=next[now][x];
                        int tmp=now;
                        while(tmp!=root){
                                ans+=flag[tmp];
                                flag[tmp]=0;
                                tmp=fail[tmp];
                        }
                }
                return ans;
        }
}ac;
int main()
{
        int t, n, i;
        scanf("%d",&t);
        while(t--){
                scanf("%d",&n);
                ac.init();
                for(i=0;i<n;i++){
                        scanf("%s",s);
                        ac.Insert(s);
                }
                ac.Build();
                scanf("%s",s);
                printf("%d\n",ac.Query(s));
        }
        return 0;
}

你可能感兴趣的:(编程,ACM,算法与数据结构,AC自动机)