#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<string.h> using namespace std; struct triee { int son[4]; char value; char step; int fail,fa; bool isright; }; triee trie[10000020]; char s[10000020]; char temp[1000]; int n, m,root=1; int diantot = 2; int num[100020]; int cc(char a) { if (a == 'N')return 0; if (a == 'E')return 1; if (a == 'S')return 2; if (a == 'W')return 3; } void insert(char *s, int tot,int kind) { int temp = root; for (int i = 0; i < tot; i++) { int k = cc(s[i]); if (trie[temp].son[k] == 0)trie[diantot].step = trie[temp].step+1,trie[diantot].fa=temp,trie[temp].son[k] = diantot++; temp = trie[temp].son[k]; trie[temp].value = s[i]; } num[kind] = temp; } void getfail() { queue<int>que; que.push(1); while (!que.empty()) { int now = que.front(); que.pop(); for (int i = 0; i < 4; i++) { int temp = trie[now].son[i]; int fa = trie[now].fail; while (fa&&trie[fa].son[i] == 0)fa = trie[fa].fail; if (!temp) { trie[now].son[i] = trie[fa].son[i]; } else { trie[temp].fail = trie[fa].son[i]; que.push(temp); } } } } void up(int num) { trie[num].isright = 1; num = trie[num].fail; while (num&&trie[num].isright == 0)trie[num].isright = 1, num = trie[num].fail; } void insertt(char *s, int tot) { int temp = root; for (int i = 0; i < tot; i++) { int k = cc(s[i]); int nextt = trie[temp].son[k]; up(nextt); temp = nextt; } } int main() { scanf("%d%d", &n, &m); int l = 0; scanf("%s", s); l = strlen(s); for (int i = 0; i < m; i++) { int tot = 0; scanf("%s", temp); tot = strlen(temp); insert(temp, tot,i); } for (int i = 0; i < 4; i++)trie[0].son[i] = 1; getfail(); insertt(s, l); for (int i = 0; i < m; i++) { int fa = num[i]; while (fa&&trie[fa].isright == 0)fa = trie[fa].fa; printf("%d\n", trie[fa].step); } return 0; }
//改进后的ac自动机
bzoj4327
最新推荐文章于 2018-10-07 11:15:00 发布