hdu 3065 病毒侵袭持续中 (ac自动机)

来源:互联网 发布:简易海报设计软件 编辑:程序博客网 时间:2024/06/02 00:57

题意:

给出一个病毒库,然后给出一个网站,求这个病毒库中的病毒在这个网站上出现的次数。

题解:

直接ac自动机,然后用set保存出现在这个网站上的病毒编号。

#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))typedef long long ll;const int oo=0x3f3f3f3f;const ll OO=1LL<<61;const ll MOD=10007;const int maxn=2000000+5;const int SIZE=1000*55;char str[1005][55];char buff[maxn];int ans[1005];set<int>StrId;struct AC{    int next[SIZE][128],fail[SIZE],end[SIZE],Q[SIZE*128];    int root,cnt;    void Init()    {        cnt=0;        root=newNode();    }    int newNode()    {        for(int i=0;i<128;i++)            next[cnt][i]=-1;        end[cnt++]=0;        return cnt-1;    }    void Insert(char buff[],int id)    {        int now=root;        int len=strlen(buff);        for(int i=0,k;i<len;i++)        {            k=buff[i];            if(next[now][k]==-1)                next[now][k]=newNode();            now=next[now][k];        }        end[now]=id;///记录编号    }    void build()    {        fail[root]=root;        int front,rear;        front=rear=0;        int now=root;        for(int i=0;i<128;i++)        {            if(next[now][i]==-1)                next[now][i]=root;            else            {                fail[next[now][i]]=root;                Q[rear++]=next[now][i];            }        }        while(front<rear)        {            now=Q[front++];            for(int i=0;i<128;i++)            {                if(next[now][i]==-1)                    next[now][i]=next[fail[now]][i];                else                {                    fail[next[now][i]]=next[fail[now]][i];                    Q[rear++]=next[now][i];                }            }        }    }    void Search(char buff[])    {        int now=root;        int len=strlen(buff);        for(int i=0;i<len;i++)        {            now=next[now][buff[i]];            int temp=now;            while(temp!=root)            {                if(end[temp])                    StrId.insert(end[temp]);                ans[end[temp]]++;                temp=fail[temp];            }        }    }    void Debug()    {        for(int i=0;i<cnt;i++)        {            printf("id=%3d fail=%3d end=%3d child=[",i,fail[i],end[i]);            for(int j=0;j<26;j++)                printf(" %3d",next[i][j]);            printf(" ]\n");        }    }};AC ac;int main(){    int n,m,cnt;    while(scanf("%d",&n)!=EOF)    {        memset(ans,0,sizeof ans);        StrId.clear();        ac.Init();        for(int i=1;i<=n;i++)        {            scanf("%s",str[i]);            ac.Insert(str[i],i);        }        ac.build();        scanf("%s",buff);        ac.Search(buff);        for(set<int>::iterator it=StrId.begin();it!=StrId.end();++it)            printf("%s: %d\n",str[*it],ans[*it]);    }    return 0;}




0 0
原创粉丝点击