HDU 2222 Keywords Search(AC自动机模版)

题目链接

比着模版改的。改成静态的,一直在RE与超内存之间徘徊,最后出现了WA,忘记了一个初始化。。。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 using namespace std;
  6 char str[1000001];
  7 int t;
  8 int tire[252222][26];
  9 int que[352222];
 10 int o[252222];
 11 int fail[252222];
 12 void CL()
 13 {
 14     memset(tire,-1,sizeof(tire));
 15     memset(fail,-1,sizeof(fail));
 16     memset(o,0,sizeof(o));
 17     t = 1;
 18 }
 19 void insert(char *s)
 20 {
 21     int i,root,len;
 22     len = strlen(s);
 23     root = 0;
 24     for(i = 0;i < len;i ++)
 25     {
 26         if(tire[root][s[i]-'a'] == -1)
 27         tire[root][s[i]-'a'] = t ++;
 28         root = tire[root][s[i]-'a'];
 29     }
 30     o[root] ++;
 31 }
 32 void build_ac()
 33 {
 34     int head,tail,front,temp,i;
 35     head = tail = 0;
 36     que[tail++] = 0;
 37     while(head != tail)
 38     {
 39         front = que[head++];
 40         for(i = 0;i < 26;i ++)
 41         {
 42             if(tire[front][i] != -1)
 43             {
 44                 if(front == 0)
 45                 fail[tire[front][i]] = 0;
 46                 else
 47                 {
 48                     temp = fail[front];
 49                     while(temp != -1)
 50                     {
 51                         if(tire[temp][i] != -1)
 52                         {
 53                             fail[tire[front][i]] = tire[temp][i];
 54                             break;
 55                         }
 56                         temp = fail[temp];
 57                     }
 58                     if(temp == -1) fail[tire[front][i]] = 0;
 59                 }
 60                 que[tail++] = tire[front][i];
 61             }
 62         }
 63     }
 64 }
 65 int query(char *s)
 66 {
 67     int i,len,root,temp,ans,key;
 68     ans = 0;
 69     root = 0;
 70     len = strlen(s);
 71     for(i = 0;i < len;i ++)
 72     {
 73         temp = s[i] - 'a';
 74         while(tire[root][temp] == -1&&root != 0)
 75         root = fail[root];
 76         root = tire[root][temp];
 77         if(root == -1) root = 0;
 78         key = root;
 79         while(key != 0&&o[key] != -1)
 80         {
 81             ans += o[key];
 82             o[key] = -1;
 83             key = fail[key];
 84         }
 85 
 86     }
 87     return ans;
 88 }
 89 int main()
 90 {
 91     int cas,i,n;
 92     scanf("%d",&cas);
 93     while(cas--)
 94     {
 95         scanf("%d",&n);
 96         CL();
 97         for(i = 0;i < n;i ++)
 98         {
 99             scanf("%s",str);
100             insert(str);
101         }
102         build_ac();
103         scanf("%s",str);
104         printf("%d\n",query(str));
105     }
106     return 0;
107 }

 新的模版,写起来更短一点。。还要理解一下。

  1 #include<iostream>
  2  #include<cstdio>
  3  #include<cstring>
  4  #include<string>
  5  using namespace std;
  6  char str[1000001];
  7  int t;
  8  int tire[252222][26];
  9  int que[352222];
 10  int o[252222];
 11  int fail[252222];
 12  void CL()
 13  {
 14      memset(tire,-1,sizeof(tire));
 15      memset(o,0,sizeof(o));
 16      t = 1;
 17  }
 18  void insert(char *s)
 19  {
 20      int i,root,len;
 21      len = strlen(s);
 22      root = 0;
 23      for(i = 0;i < len;i ++)
 24      {
 25          if(tire[root][s[i]-'a'] == -1)
 26          tire[root][s[i]-'a'] = t ++;
 27          root = tire[root][s[i]-'a'];
 28      }
 29      o[root] ++;
 30  }
 31  void build_ac()
 32  {
 33      int head,tail,front,i;
 34      head = tail = 0;
 35      for (i = 0; i < 26; i++)
 36      {
 37          if (tire[0][i]  != -1)
 38          {
 39              fail[tire[0][i]] = 0;
 40              que[tail++] = tire[0][i];
 41          }
 42          else
 43          {
 44              tire[0][i] = 0;
 45          }
 46      }
 47      while(head != tail)
 48      {
 49          front = que[head++];
 50          for(i = 0; i < 26; i ++)
 51          {
 52              if(tire[front][i] != -1)
 53              {
 54                  que[tail++] = tire[front][i];
 55                  fail[tire[front][i]] = tire[fail[front]][i];
 56              }
 57              else
 58              {
 59                  tire[front][i] = tire[fail[front]][i];
 60              }
 61          }
 62      }
 63  }
 64  int query(char *s)
 65  {
 66      int i,len,root,temp,ans,key;
 67      ans = 0;
 68      root = 0;
 69      len = strlen(s);
 70      for(i = 0;i < len;i ++)
 71      {
 72          temp = s[i] - 'a';
 73          root = tire[root][temp];
 74          key = root;
 75          while(key != 0&&o[key] != -1)
 76          {
 77              ans += o[key];
 78              o[key] = -1;
 79              key = fail[key];
 80          }
 81      }
 82      return ans;
 83  }
 84  int main()
 85  {
 86      int cas,i,n;
 87      scanf("%d",&cas);
 88      while(cas--)
 89      {
 90          scanf("%d",&n);
 91          CL();
 92          for(i = 0;i < n;i ++)
 93          {
 94              scanf("%s",str);
 95              insert(str);
 96          }
 97          build_ac();
 98          scanf("%s",str);
 99          printf("%d\n",query(str));
100      }
101      return 0;
102  }

 

posted @ 2013-04-21 22:01  Naix_x  阅读(262)  评论(0编辑  收藏  举报