HDU 6208 The Dominator of Strings ——(青岛网络赛,AC自动机)

Posted Storm_Spirit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6208 The Dominator of Strings ——(青岛网络赛,AC自动机)相关的知识,希望对你有一定的参考价值。

  最长的才可能成为答案,那么除了最长的以外全部insert到自动机里,再拿最长的去match,如果match完以后cnt全被清空了,那么这个最长串就是答案。事实上方便起见这个最长串一起丢进去也无妨,而且更好写(时间也没有慢特别多)。

  另外需要注意的一点是init()里头的memset只需要清空之前用过的节点而不是所有节点,这是经常被卡的一点。

  代码如下:

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <string.h>
  4 #include <queue>
  5 #include <vector>
  6 using namespace std;
  7 const int MAX_N = 100000 + 50;
  8 const int MAX_Tot = 100000 + 50;
  9 
 10 struct Aho
 11 {
 12     struct state
 13     {
 14         int nxt[26];
 15         int fail,cnt;
 16     }stateTable[MAX_Tot];
 17 
 18     int size;
 19 
 20     queue<int> que;
 21 
 22     void init()
 23     {
 24         while(que.size()) que.pop();
 25         for(int i=0;i<size;i++)
 26         {
 27             memset(stateTable[i].nxt,0,sizeof(stateTable[i].nxt));
 28             stateTable[i].fail = stateTable[i].cnt = 0;
 29         }
 30         size = 1;
 31     }
 32 
 33     void insert(char *s)
 34     {
 35         int n = strlen(s);
 36         int now = 0;
 37         for(int i=0;i<n;i++)
 38         {
 39             char c = s[i];
 40             if(!stateTable[now].nxt[c-a])
 41                 stateTable[now].nxt[c-a] = size++;
 42             now = stateTable[now].nxt[c-a];
 43         }
 44         stateTable[now].cnt++;
 45     }
 46 
 47     void build()
 48     {
 49         stateTable[0].fail = -1;
 50         que.push(0);
 51 
 52         while(que.size())
 53         {
 54             int u = que.front();que.pop();
 55             for(int i=0;i<26;i++)
 56             {
 57                 if(stateTable[u].nxt[i])
 58                 {
 59                     if(u == 0) stateTable[stateTable[u].nxt[i]].fail = 0;
 60                     else
 61                     {
 62                         int v = stateTable[u].fail;
 63                         while(v != -1)
 64                         {
 65                             if(stateTable[v].nxt[i])
 66                             {
 67                                 stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
 68                                 break;
 69                             }
 70                             v = stateTable[v].fail;
 71                         }
 72                         if(v == -1) stateTable[stateTable[u].nxt[i]].fail = 0;
 73                     }
 74                     que.push(stateTable[u].nxt[i]);
 75                 }
 76             }
 77         }
 78     }
 79 
 80     //bool mark[MAX_Tot];
 81     void Get(int u)
 82     {
 83         while(u)
 84         {
 85             if(stateTable[u].cnt == -1) break;
 86             stateTable[u].cnt = -1;
 87             u = stateTable[u].fail;
 88         }
 89     }
 90 
 91     int match(char *s)
 92     {
 93         //memset(mark, 0, sizeof mark);
 94         int n = strlen(s);
 95         int res = 0, now = 0;
 96         for(int i=0;i<n;i++)
 97         {
 98             char c = s[i];
 99             if(stateTable[now].nxt[c-a]) now = stateTable[now].nxt[c-a];
100             else
101             {
102                 int p = stateTable[now].fail;
103                 while(p != -1 && stateTable[p].nxt[c-a] == 0) p = stateTable[p].fail;
104                 if(p == -1) now = 0;
105                 else now = stateTable[p].nxt[c-a];
106             }
107 
108             Get(now);
109         }
110         for(int i=1;i<size;i++) if(stateTable[i].cnt > 0) return 0;
111         return 1;
112     }
113 }aho;
114 
115 int T,n;
116 char s[MAX_N], t[MAX_N];
117 
118 int main()
119 {
120     int T;scanf("%d",&T);
121     while(T--)
122     {
123         vector<char> v;
124         aho.init();
125         scanf("%d",&n);
126         int maxn = 0;
127         for(int i=1;i<=n;i++)
128         {
129             scanf("%s",s);
130             //aho.insert(s);
131             int sz = strlen(s);
132             for(int j=0;j<sz;j++) v.push_back(s[j]);
133             v.push_back(#);
134             if(sz > maxn)
135             {
136                 maxn = sz;
137                 strcpy(t, s);
138             }
139         }
140         int tot = 0;
141         for(int i=0;i<v.size();i++)
142         {
143             if(v[i] == #)
144             {
145                 s[tot++] = 0;
146                 tot = 0;
147                 if(strcmp(s, t)) aho.insert(s);
148             }
149             else s[tot++] = v[i];
150         }
151         aho.build();
152         int ans = aho.match(t);
153         if(ans) puts(t);
154         else puts("No");
155     }
156 }

 

以上是关于HDU 6208 The Dominator of Strings ——(青岛网络赛,AC自动机)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 6208 (字符串hash)

hdu 5318 The Goddess Of The Moon

HDU 1010 Tempter of the Bone

hdu 5318 The Goddess Of The Moon 矩阵高速幂

hdu 1010 Tempter of the Bone

HDU 1010 Tempter of the Bone