HDu-2896 病毒侵袭,AC自动机模板题!

来源:互联网 发布:tensorflow spark 编辑:程序博客网 时间:2024/06/08 12:00

病毒侵袭

   模板题,不多说了。。

   题意:n个不同的字符串分别代表病毒特征,给出m次查询,每次一个字符串(网址),求这个字符串中有几个病毒特征,分别从大到小输出编号,最后输出所有的带病毒网址个数。格式请看样例。

   思路:典型AC自动机模板题,建一个Trie树,叶节点赋病毒的编号,然后依次匹配,用set存入编号即可,如果不带病毒不用输出来。这题很容易MLE,动态建树释放内存,所以采用静态建树,可以参考POJ Phone List。注意用C++提交。

const int N=129;//可见字符很多,注意不能仅用26char str[10001],s[205];int head,tail,cnt;set<int>g[1005];struct tree{    int f;    tree *fail;    tree *next[N];}*q[500010],*root,memory[500010];void insert(char *s,int i){    tree *p=root;    while(*s!='\0')    {        int id=(int)(*s);        if(p->next[id]==NULL) p->next[id]=&memory[cnt++];        p=p->next[id];        s++;    }    p->f=i;}void build(){    root->fail=NULL;    q[head++]=root;    while(head!=tail)    {        tree *temp=q[tail++];        tree *p=NULL;        for(int i=0;i<N;i++)            if(temp->next[i])        {            if(temp==root) temp->next[i]->fail=root;            else            {                p=temp->fail;                while(p!=NULL)                {                    if(p->next[i])                    {                        temp->next[i]->fail=p->next[i];                        break;                    }                    p=p->fail;                }                if(p==NULL) temp->next[i]->fail=root;            }            q[head++]=temp->next[i];        }    }}void find(int i,char *s){    tree *p=root;    while(*s!='\0')    {        int id=(int)(*s);        while(p->next[id]==NULL&&p!=root) p=p->fail;        p=p->next[id];        p=p==NULL?root:p;        tree *temp=p;        while(temp!=root)        {            if(temp->f!=0) g[i].insert(temp->f);            temp=temp->fail;        }        s++;    }}int main(){    int n,m;    while(~scanf("%d",&n))    {        cnt=head=tail=0;        int tot=0;        root=&memory[cnt++];        for(int i=0; i<1005; i++) g[i].clear();        for(int i=1; i<=n; i++)        {            scanf("%s",s);            insert(s,i);        }        build();        scanf("%d",&m);        int t=1;        while(m--)        {            scanf("%s",str);            find(t,str);            t++;            if(g[t-1].size())            {                printf("web %d:",t-1);                for(set<int>::iterator it=g[t-1].begin(); it!=g[t-1].end(); it++)                    printf(" %d",*it);                printf("\n");                tot++;            }        }        printf("total: %d\n",tot);    }    return 0;}/**********************************************************   LYQ    ********************************   YES    ****************UserID: secrecy                         **RunOJ:                                  **RunID:                                  **Submit time:                            **Language: G++                           **Result: Accepted                        **time:                                   **Memory:                                 **Length:                                 **School: NYIST                           **Blog: http://blog.csdn.net/nyist_tc_lyq **QQ:                                     **Tel:                                    ******************************************/



0 0
原创粉丝点击