最长的才可能成为答案,那么除了最长的以外全部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 }
时间: 2024-10-12 22:48:12