[HDU 2222]Keywords Search[AC自动机]

来源:互联网 发布:k60单片机介绍 编辑:程序博客网 时间:2024/05/22 16:44

题意:

多模式串匹配.

思路:

AC自动机,注意回溯.

优化fail建立过程.


#include<cstring>#include<cstdio>#include<algorithm>using namespace std;const int MAXN = 240055;const int MAXL = 1000005;struct AC_machine{    int fail[MAXN];    int sz;    int ch[MAXN][26];    int ID[128];    int n;    char str[MAXL];    int Q[MAXN];    int v[MAXN];    void Init()    {        sz = 1;        memset(ch[0],0,sizeof(ch[0]));        memset(v,0,sizeof(v));        fail[0] = 0;        for(int i=0;i<26;i++)  ID[i+'a'] = i;    }    void Insert(char s[])    {        int cur = 0;        for(int i=0;s[i];i++)        {            int c = ID[s[i]];            if(!ch[cur][c])            {                memset(ch[sz],0,sizeof(ch[sz]));                ch[cur][c] = sz++;            }            cur = ch[cur][c];        }        v[cur]++;    }    void Input()    {        scanf("%d",&n);        char s[55];        for(int i=0;i<n;i++)        {            scanf("%s",s);            Insert(s);        }        scanf("%s",str);    }    void Build()    {        int st = 0, en = 0;        for(int i=0;i<26;i++)        {            if(ch[0][i])            {                fail[ch[0][i]] = 0;                Q[en++] = ch[0][i];            }        }        while(st!=en)        {            int cur = Q[st++];            for(int i=0;i<26;i++)            {                int &v = ch[cur][i];                if(v)                {                    Q[en++] = v;                    fail[v] = ch[fail[cur]][i];                }                else                {                    v = ch[fail[cur]][i];//优化                }            }        }    }    void solve()    {        int ans = 0,j = 0,tmp;        for(int i=0;str[i];i++)        {            if(ch[j][ID[str[i]]])    j = ch[j][ID[str[i]]];            else            {                while(j && !ch[j][ID[str[i]]])  j = fail[j];                if(ch[j][ID[str[i]]])   j = ch[j][ID[str[i]]];            }            tmp = j;            while(tmp && v[tmp])            {                ans += v[tmp];                v[tmp] = 0;                tmp = fail[tmp];            }        }        printf("%d\n",ans);    }} AC;int main(){    int T;    scanf("%d",&T);    while(T--)    {        AC.Init();        AC.Input();        AC.Build();        AC.solve();    }}








原创粉丝点击