hdu3695--Computer Virus on Planet Pandora(AC自动机)

题目:一些字典,然后给出一个主串,问正向和反向的一起出现了多少个模式串

建好AC自动机后,正向和反向扫描一遍就行了。

 

注意原串的解析

View Code
  1 //Accepted    3695    765MS    86556K    2822 B    C++
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <cmath>
  6 #include <algorithm>
  7 using namespace std;
  8 const int inf=1<<28;
  9 const int mMax=6000005;
 10 class node{
 11 public:
 12     int id;
 13     int vis;  //前缀记录标志
 14     node *next[26],*fail;
 15     node(){
 16         vis=0;
 17         fail=NULL;
 18         for(int i=0;i<26;i++)next[i]=NULL;
 19     }
 20 }*root,*que[mMax];
 21 char str[mMax],str2[mMax],temp[mMax];
 22 void insert(char *s){    //构造前缀树
 23     int i;
 24     node *r=root;
 25     int l=strlen(s);
 26     for(i=0;i<l;i++){
 27         int loc=s[i]-'A';
 28         if(r->next[loc]==NULL){
 29             r->next[loc]=new node();
 30         }
 31         r=r->next[loc];
 32     }
 33     r->vis++;
 34 }
 35 
 36 void acAuto(){      //用bfs为每个节点设定fail指针
 37     int i,head=0,tail=0;
 38     node *p,*tmp;
 39     root->fail=NULL;
 40     que[tail++]=root;
 41     while(head<tail){
 42         tmp=que[head++];
 43         for(i=0;i<26;i++){
 44             if(tmp->next[i]==NULL)continue;
 45             if(tmp==root){
 46                 tmp->next[i]->fail=root;
 47             }
 48             else {
 49                 for(p=tmp->fail;p!=NULL;p=p->fail){
 50                     if(p->next[i]!=NULL){
 51                         tmp->next[i]->fail=p->next[i];
 52                         break;
 53                     }
 54                 }
 55                 if(p==NULL){
 56                     tmp->next[i]->fail=root;
 57                 }
 58             }
 59             que[tail++]=tmp->next[i];
 60         }
 61     }
 62 }
 63 
 64 int search(char *msg){//不同题不同的查询
 65     int i,idx,ans=0;
 66     node *p=root,*tmp;
 67     for(i=0;msg[i];i++){
 68         idx=msg[i]-'A';
 69         while(p->next[idx]==NULL&&p!=root){
 70             p=p->fail;
 71         }
 72         p=p->next[idx];
 73         if(p==NULL)p=root;
 74         for(tmp=p;tmp!=NULL&&tmp->vis!=-1;tmp=tmp->fail){
 75             ans+=tmp->vis;
 76             tmp->vis=-1;
 77         }
 78     }
 79     return ans;
 80 }
 81 void Decode(char *str){  
 82     
 83     int i = 0,j = 0,q,k,tpk;  
 84     while (str[i]) {  
 85         
 86         if (str[i] != '[')  
 87             temp[j++] = str[i++];  
 88         else {  
 89             
 90             for (q = 0,k = i + 1; str[k] >= '0' && str[k]<= '9'; ++k)  
 91                 q = q * 10 + str[k] - '0';  
 92             for (tpk = 1; tpk <= q; ++tpk)  
 93                 temp[j++] = str[k];  
 94             i = k + 2;  
 95         }  
 96     }  
 97     temp[j] = '\0';  
 98     strcpy(str,temp);  
 99 } 
100 int main(){
101     int cas,n;
102     char str1[1005];
103     scanf("%d",&cas);
104     while(cas--){
105         scanf("%d",&n);
106         root=new node();
107         while(n--){
108             scanf("%s",str1);
109             insert(str1);
110         }
111         acAuto();
112         scanf("%s",str);
113         Decode(str);
114         int j=0;
115         for(int i = strlen(str) - 1; i >= 0;i--,j++)
116             str2[j] = str[i];
117         str2[j]='\0';
118         printf("%d\n",search(str) + search(str2));
119     }
120     return 0;
121 }

 

 

posted @ 2012-10-04 16:18  Wheat″  阅读(391)  评论(0)    收藏  举报