HDU 3695 Computer Virus on Planet Pandora AC自动机

来源:互联网 发布:php获取时间 编辑:程序博客网 时间:2024/05/18 03:35
        此题为2010年区域赛福州赛区的银牌题,但是其实就是一个AC自动机的裸题,很不明白这么一个裸题当年竟然只有一半的队伍A掉,具体就是先给n个字符串,最后给一个字符串,问这个字符串中共计包含多少个前面的字符串,只是给定的串中包含【NA】,N代表一个数字,A代表一个字母,表示此位置共有N个重复的A字母,这个只是对AC自动机模板进行一个简单的处理即可,此处我用了KDD的AC自动机板板,KDD谢谢哈。。。具体代码如下:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN=250000+10;const int sigma_size=26;const int M=5100000+100;int n,sz,head,tail;char s[M],t[M];struct node{    int cnt,flag;    node *next[sigma_size],*fail;}trie[MAXN],*root,*que[MAXN];struct AC{    node *createnode()    {        for(int k=0;k<sigma_size;k++)            trie[sz].next[k]=NULL;        trie[sz].cnt=1; trie[sz].fail=NULL;        trie[sz].flag=0;        return &trie[sz++];    }    void init()    {        sz=0;        head=tail=0;        root=createnode();    }    void insert(char *str)    {        int len=strlen(str);        node *p=root;        p->cnt=1;        for(int i=0;i<len;i++)        {            int k=str[i]-'A';            if(p->next[k]==NULL)                p->next[k]=createnode();            p=p->next[k];        }        p->cnt=p->flag=1;    }    void get_fail()    {        que[tail++]=root;        while(head<tail)        {            node *p=que[head++];            for(int k=0;k<sigma_size;k++)                if(p->next[k])                {                    if(p==root)                        p->next[k]->fail=root;                    else                    {                        p->next[k]->fail=p->fail->next[k];                    }                    que[tail++]=p->next[k];                }                else                {                    if(p==root)                        p->next[k]=root;                    else                        p->next[k]=p->fail->next[k];                }        }    }    int query(char *str)    {        int i=0,ans=0;        node *p=root;        while(str[i])        {            int k=str[i++]-'A';            p=p->next[k];            if(p->cnt)            {                node *temp=p;                while(temp!=root)                {                    if(temp->flag)                        ans+=temp->cnt;                    temp->cnt=0; temp=temp->fail;                }            }        }        return ans;    }}ac;int main(){ //   freopen("in.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        ac.init();        for(int i=0;i<n;i++)        {            char str[1000+100];            scanf("%s",str);            ac.insert(str);        }        ac.get_fail();        scanf("%s",t);        int len=0;        int m=strlen(t);        for(int i=0;i<m;)            if(t[i]>='A' && t[i]<='Z')                s[len++]=t[i++];            else if(t[i]=='[')            {                i++;                int k=0;                while(t[i]>='0' && t[i]<='9')                    k=k*10+(t[i++]-'0');                for(int j=0;j<k;j++)                    s[len++]=t[i];                i+=2;            }        s[len]='\0';        int ans=0;        ans+=ac.query(s);        reverse(s,s+strlen(s));        ans+=ac.query(s);        printf("%d\n",ans);    }    return 0;}

0 0
原创粉丝点击