DataStructure

HDU-3065-病毒侵袭持续中(AC自动机)

2019-08-08  本文已影响0人  雨落八千里

病毒侵袭持续中

num数组记录的还是病毒id,vis数组记录的是病毒出现的次数,多组输入。字典树的大小是字符长度乘以个数搞了半天超内存

#include<bits/stdc++.h>
using namespace std;
const int M=50005;
char s[1010][60];
int tree[M][128];
int num[M];
int fail[M];
int pos;
int vis[1100];
char str[2000100];
void insert(char *s,int cnt)
{
    int len=strlen(s);
    int root=0;
    for(int i=0; i<len; i++)
    {
        int x=s[i];
        if(!tree[root][x])
        {
            tree[root][x]=pos;
            pos++;
        }
        root=tree[root][x];
    }
    num[root]=cnt;
}
void getfail( )
{
    queue<int>qu;
    for(int i=0; i<128; i++)
    {
        if(tree[0][i])
        {
            fail[tree[0][i]]=0;
            qu.push(tree[0][i]);
        }
    }
    while(!qu.empty( ))
    {
        int u=qu.front( );
        qu.pop( );
        for(int i=0; i<128; i++)
        {
            if(tree[u][i])
            {
                fail[tree[u][i]]=tree[fail[u]][i];
                qu.push(tree[u][i]);
            }
            else
            {
                tree[u][i]=tree[fail[u]][i];
            }

        }
    }
}
void query(char *s)
{
    int len=strlen(s);
    int root=0;
    for(int i=0; i<len; i++)
    {
        int x=s[i];
        root=tree[root][x];
        for(int j=root; j&&num[j]; j=fail[j])
        {
            vis[num[j]]++;
        }
    }
}
int main( )
{
    int n;
    while(~scanf("%d",&n))
    {
        pos=1;
        memset(fail,0,sizeof(fail));
        memset(tree,0,sizeof(tree));
        memset(vis,0,sizeof(vis));
        memset(num,0,sizeof(num));
        for(int i=1; i<=n; i++)
        {
           scanf("%s",s[i]);
            insert( s[i] , i);
        }
        fail[0]=0;
        getfail( );
        scanf("%s",str);
        query(str);
        for(int i=1; i<=n; i++)
        {
            if(vis[i]!=0)
            {
                printf("%s: %d\n",s[i],vis[i]);
            }
        }
    }
    return 0;

}
上一篇下一篇

猜你喜欢

热点阅读