hdu3065 病毒侵袭持续中(AC自动机)

来源:互联网 发布:485接口数据交换 编辑:程序博客网 时间:2024/06/10 13:49

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

题意:

给你n个串,再给你一个大长串,问你之前的n个串中出现过的串的次数。

解:

AC自动机解决,使用vis数组记录当前字符串出现的次数。每当匹配成功则+1,最后输出非0的vis就行。

关于AC自动机可看我的博客:AC自动机讲解+模板

代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <queue>using namespace std;const int maxn = 2e6+5;const int N = 55;char s[1005][N],s1[N],str[maxn];int vis[1005];struct Tries{    int nxt[1005*N][128],fail[1005*N],end[1005*N];    int root,L;    int newnode(){        for(int i = 0; i < 128 ; i++ )            nxt[L][i]=-1;        end[L++]=-1;    return L-1;    }    void init(){        L=0;        root = newnode();    }    void insert(char buf[],int id){        int len = strlen(buf);        int now = root;        for(int i = 0; i < len ; i++ )        {            if(nxt[now][buf[i]] == -1)                nxt[now][buf[i]] =newnode();            now = nxt[now][buf[i]];        }        end[now]=id ;    }    void build(){        queue<int>Q;        fail[root] = root;        for(int i = 0; i < 128; i++ )            if(nxt[root][i]==-1)                nxt[root][i] = root;            else            {                fail[nxt[root][i]] = root;/* *** */                Q.push(nxt[root][i]);            }        while(!Q.empty())        {            int now = Q.front();            Q.pop();            for(int i = 0;i < 128; i++ )                if(nxt[now][i]==-1)                    nxt[now][i] = nxt[fail[now]][i]; /* *** */                else                {                    fail[nxt[now][i]] = nxt[fail[now]][i];                    Q.push(nxt[now][i]);                }        }    }    void query(char buf[])    {        memset(vis,0,sizeof(vis));        int len = strlen(buf);        int now = root;        //int res = 0;        for(int i = 0;i < len ; i++ )        {            now = nxt[now][buf[i]];            int tmp = now;            while( tmp != root)            {                if(end[tmp]!=-1)                    vis[end[tmp]]++;                tmp = fail[tmp];            }        }        //return res;    }};Tries AC;int main(){    int n;    while(~scanf("%d",&n))    {        AC.init();        for(int i=1;i<=n;i++)        {            scanf("%s",s1);            strcpy(s[i],s1);            AC.insert(s[i],i);        }        AC.build();        scanf("%s",str);        AC.query(str);        for(int i=1;i<=n;i++)        {            if(vis[i]!=0)            {                printf("%s: %d\n",s[i],vis[i]);            }        }    }    return 0;}


阅读全文
0 0
原创粉丝点击