• HDU 3065 病毒侵袭持续中(AC自动机)


      这题数据太水,一开始没有加上Get的方法也能AC。。话说AC自动机中一定要注意加上Get的方法!(不然,同一个后缀的其他单词就没被算上了。)

      代码如下:

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <string.h>
      4 #include <queue>
      5 #include <string>
      6 #include <map>
      7 #include <iostream>
      8 using namespace std;
      9 const int MAX_N = 2000000 + 50;
     10 const int MAX_Tot = 1000*50 + 50;
     11 
     12 int ans[1000+5];
     13 map<int,string> M;
     14 
     15 struct Aho
     16 {
     17     struct state
     18     {
     19         int nxt[26];
     20         int fail,cnt;
     21     }stateTable[MAX_Tot];
     22 
     23     int size;
     24 
     25     queue<int> que;
     26 
     27     void init()
     28     {
     29         while(que.size()) que.pop();
     30         for(int i=0;i<MAX_Tot;i++)
     31         {
     32             memset(stateTable[i].nxt,0,sizeof(stateTable[i].nxt));
     33             stateTable[i].fail = stateTable[i].cnt = 0;
     34         }
     35         size = 1;
     36     }
     37 
     38     void insert(char *s,int which)
     39     {
     40         int n = strlen(s);
     41         int now = 0;
     42         for(int i=0;i<n;i++)
     43         {
     44             char c = s[i];
     45             if(!stateTable[now].nxt[c-'A'])
     46                 stateTable[now].nxt[c-'A'] = size++;
     47             now = stateTable[now].nxt[c-'A'];
     48         }
     49         stateTable[now].cnt = which;
     50     }
     51 
     52     void build()
     53     {
     54         stateTable[0].fail = -1;
     55         que.push(0);
     56 
     57         while(que.size())
     58         {
     59             int u = que.front();que.pop();
     60             for(int i=0;i<26;i++)
     61             {
     62                 if(stateTable[u].nxt[i])
     63                 {
     64                     if(u == 0) stateTable[stateTable[u].nxt[i]].fail = 0;
     65                     else
     66                     {
     67                         int v = stateTable[u].fail;
     68                         while(v != -1)
     69                         {
     70                             if(stateTable[v].nxt[i])
     71                             {
     72                                 stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
     73                                 break;
     74                             }
     75                             v = stateTable[v].fail;
     76                         }
     77                         if(v == -1) stateTable[stateTable[u].nxt[i]].fail = 0;
     78                     }
     79                     que.push(stateTable[u].nxt[i]);
     80                 }
     81             }
     82         }
     83     }
     84     
     85     void Get(int u)
     86     {
     87         while(u)
     88         {
     89             ans[stateTable[u].cnt] ++;
     90             u = stateTable[u].fail;
     91         }
     92     }
     93 
     94     void match(char *s)
     95     {
     96         int n = strlen(s);
     97         int now = 0;
     98         for(int i=0;i<n;i++)
     99         {
    100             char c = s[i];
    101             if(c<'A' || c>'Z') {now = 0;continue;}
    102             if(stateTable[now].nxt[c-'A']) now = stateTable[now].nxt[c-'A'];
    103             else
    104             {
    105                 int p = stateTable[now].fail;
    106                 while(p != -1 && stateTable[p].nxt[c-'A'] == 0) p = stateTable[p].fail;
    107                 if(p == -1) now = 0;
    108                 else now = stateTable[p].nxt[c-'A'];
    109             }
    110             if(stateTable[now].cnt)
    111             {
    112                 Get(now);
    113                 //ans[stateTable[now].cnt] ++;
    114                 /*
    115                     一定要用Get这样的方法,
    116                     不然,同一个后缀的无法被算上了
    117                 */
    118             }
    119         }
    120     }
    121 }aho;
    122 
    123 int n;
    124 char s[MAX_N];
    125 
    126 int main()
    127 {
    128     while(scanf("%d",&n)==1)
    129     {
    130         memset(ans,0,sizeof(ans));
    131         M.clear();
    132         aho.init();
    133         for(int i=1;i<=n;i++)
    134         {
    135             scanf("%s",s);
    136             M[i] = s;
    137             aho.insert(s,i);
    138         }
    139         aho.build();
    140         scanf("%s",s);
    141         aho.match(s);
    142         for(int i=1;i<=n;i++)
    143         {
    144             if(ans[i])
    145             {
    146                 cout << M[i] << ": " << ans[i] << endl;
    147             }
    148         }
    149     }
    150 }

     ————————————————————————————————————————————

      发现上面的代码有问题(虽然能AC),正确代码如下:

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <string.h>
      4 #include <queue>
      5 #include <string>
      6 #include <map>
      7 #include <iostream>
      8 using namespace std;
      9 const int MAX_N = 2000000 + 50;
     10 const int MAX_Tot = 1000*50 + 50;
     11 
     12 int ans[1000+5];
     13 map<int,string> M;
     14 
     15 struct Aho
     16 {
     17     struct state
     18     {
     19         int nxt[26];
     20         int fail,cnt;
     21     }stateTable[MAX_Tot];
     22 
     23     int size;
     24 
     25     queue<int> que;
     26 
     27     void init()
     28     {
     29         while(que.size()) que.pop();
     30         for(int i=0;i<MAX_Tot;i++)
     31         {
     32             memset(stateTable[i].nxt,0,sizeof(stateTable[i].nxt));
     33             stateTable[i].fail = stateTable[i].cnt = 0;
     34         }
     35         size = 1;
     36     }
     37 
     38     void insert(char *s,int which)
     39     {
     40         int n = strlen(s);
     41         int now = 0;
     42         for(int i=0;i<n;i++)
     43         {
     44             char c = s[i];
     45             if(!stateTable[now].nxt[c-'A'])
     46                 stateTable[now].nxt[c-'A'] = size++;
     47             now = stateTable[now].nxt[c-'A'];
     48         }
     49         stateTable[now].cnt = which;
     50     }
     51 
     52     void build()
     53     {
     54         stateTable[0].fail = -1;
     55         que.push(0);
     56 
     57         while(que.size())
     58         {
     59             int u = que.front();que.pop();
     60             for(int i=0;i<26;i++)
     61             {
     62                 if(stateTable[u].nxt[i])
     63                 {
     64                     if(u == 0) stateTable[stateTable[u].nxt[i]].fail = 0;
     65                     else
     66                     {
     67                         int v = stateTable[u].fail;
     68                         while(v != -1)
     69                         {
     70                             if(stateTable[v].nxt[i])
     71                             {
     72                                 stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
     73                                 break;
     74                             }
     75                             v = stateTable[v].fail;
     76                         }
     77                         if(v == -1) stateTable[stateTable[u].nxt[i]].fail = 0;
     78                     }
     79                     que.push(stateTable[u].nxt[i]);
     80                 }
     81             }
     82         }
     83     }
     84 
     85     void Get(int u)
     86     {
     87         while(u)
     88         {
     89             ans[stateTable[u].cnt] ++;
     90             u = stateTable[u].fail;
     91         }
     92     }
     93 
     94     void match(char *s)
     95     {
     96         int n = strlen(s);
     97         int now = 0;
     98         for(int i=0;i<n;i++)
     99         {
    100             char c = s[i];
    101             if(c<'A' || c>'Z') {now = 0;continue;}
    102             if(stateTable[now].nxt[c-'A']) now = stateTable[now].nxt[c-'A'];
    103             else
    104             {
    105                 int p = stateTable[now].fail;
    106                 while(p != -1 && stateTable[p].nxt[c-'A'] == 0) p = stateTable[p].fail;
    107                 if(p == -1) now = 0;
    108                 else now = stateTable[p].nxt[c-'A'];
    109             }
    110             //if(stateTable[now].cnt)
    111             {
    112                 Get(now);
    113             }
    114         }
    115     }
    116 }aho;
    117 
    118 int n;
    119 char s[MAX_N];
    120 
    121 int main()
    122 {
    123     while(scanf("%d",&n)==1)
    124     {
    125         memset(ans,0,sizeof(ans));
    126         M.clear();
    127         aho.init();
    128         for(int i=1;i<=n;i++)
    129         {
    130             scanf("%s",s);
    131             M[i] = s;
    132             aho.insert(s,i);
    133         }
    134         aho.build();
    135         scanf("%s",s);
    136         aho.match(s);
    137         for(int i=1;i<=n;i++)
    138         {
    139             if(ans[i])
    140             {
    141                 cout << M[i] << ": " << ans[i] << endl;
    142             }
    143         }
    144     }
    145 }
    146 /*
    147 3
    148 ABCDEFG
    149 ABCDE
    150 DEF
    151 ABCDEFG
    152 */
    View Code
  • 相关阅读:
    如何使用websocket实现前后端通信
    影响MySQL的性能(一)磁盘的选择
    springboot结合日志门面SLF4j和日志实现Logback的使用
    分享一个猜数字小游戏的脚本
    关于drop table *** purge (drop后不过回收站)
    关于DateBase link(dbLINK)及同义词
    关于数据更新(update)
    关于insert into(插入值)
    关于wm_concat(把一列的值,通过','进行分隔后,合并成一个值进行显示)
    关于PIVOT(用于行转列)
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5987330.html
Copyright © 2020-2023  润新知